[
  {
    "path": ".changeset/README.md",
    "content": "# Changesets\n\nHello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works\nwith multi-package repos, or single-package repos to help you version and publish your code. You can\nfind the full documentation for it [in our repository](https://github.com/changesets/changesets).\n\nWe have a quick list of common questions to get you started engaging with this project in\n[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md).\n"
  },
  {
    "path": ".changeset/config.json",
    "content": "{\n  \"$schema\": \"https://unpkg.com/@changesets/config@3.1.3/schema.json\",\n  \"changelog\": [\"@changesets/changelog-github\", { \"repo\": \"run-llama/liteparse\" }],\n  \"commit\": false,\n  \"fixed\": [],\n  \"linked\": [],\n  \"access\": \"public\",\n  \"baseBranch\": \"main\",\n  \"updateInternalDependencies\": \"patch\",\n  \"ignore\": []\n}\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yml",
    "content": "name: Bug Report\ndescription: Report a bug (crashes, errors, unexpected behavior)\ntitle: \"[Bug] \"\nlabels: [\"bug\"]\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for taking the time to report a bug!\n\n        **Note:** If this is a parsing quality issue (incorrect text, bad formatting), please use the \"Parsing Issue\" template instead.\n\n  - type: textarea\n    id: description\n    attributes:\n      label: Description\n      description: A clear description of the bug\n    validations:\n      required: true\n\n  - type: textarea\n    id: reproduce\n    attributes:\n      label: Steps to Reproduce\n      description: How can we reproduce this issue?\n      placeholder: |\n        1. Run `lit parse ...`\n        2. See error\n    validations:\n      required: true\n\n  - type: textarea\n    id: error\n    attributes:\n      label: Error Message\n      description: The full error message or stack trace\n      render: text\n    validations:\n      required: false\n\n  - type: input\n    id: version\n    attributes:\n      label: LiteParse Version\n      description: Run `lit --version` to get this\n      placeholder: \"0.1.0\"\n    validations:\n      required: true\n\n  - type: dropdown\n    id: os\n    attributes:\n      label: Operating System\n      options:\n        - macOS (Apple Silicon)\n        - macOS (Intel)\n        - Linux\n        - Windows\n        - Other\n    validations:\n      required: true\n\n  - type: input\n    id: node\n    attributes:\n      label: Node.js Version\n      description: Run `node --version` to get this\n      placeholder: \"v20.0.0\"\n    validations:\n      required: true\n\n  - type: textarea\n    id: additional\n    attributes:\n      label: Additional Context\n      description: Any other relevant information\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\ncontact_links:\n  - name: Documentation\n    url: https://github.com/run-llama/liteparse#readme\n    about: Check the README for usage documentation\n  - name: Discussions\n    url: https://github.com/run-llama/liteparse/discussions\n    about: Ask questions and share ideas\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.yml",
    "content": "name: Feature Request\ndescription: Suggest a new feature or improvement\ntitle: \"[Feature] \"\nlabels: [\"enhancement\"]\nbody:\n  - type: textarea\n    id: problem\n    attributes:\n      label: Problem Statement\n      description: What problem would this feature solve?\n      placeholder: \"I'm always frustrated when...\"\n    validations:\n      required: true\n\n  - type: textarea\n    id: solution\n    attributes:\n      label: Proposed Solution\n      description: How do you think this should work?\n    validations:\n      required: true\n\n  - type: textarea\n    id: alternatives\n    attributes:\n      label: Alternatives Considered\n      description: Have you considered any alternative solutions or workarounds?\n    validations:\n      required: false\n\n  - type: textarea\n    id: additional\n    attributes:\n      label: Additional Context\n      description: Any other context, mockups, or examples\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/parsing_issue.yml",
    "content": "name: Parsing Issue\ndescription: Report an issue with document parsing (incorrect output, missing text, etc.)\ntitle: \"[Parsing] \"\nlabels: [\"parsing\", \"bug\"]\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        ## Important: Document Required\n\n        **Parsing issues without a reproducible example will be closed.**\n\n        To investigate parsing problems, we need to see the actual document. Please either:\n        - Attach the document to this issue (drag and drop below)\n        - Provide a public link to the document\n        - If the document is confidential, provide a minimal reproduction with a similar document\n\n  - type: textarea\n    id: description\n    attributes:\n      label: Description\n      description: Describe the parsing issue you're experiencing\n      placeholder: \"The text on page 3 is missing / The table formatting is incorrect / etc.\"\n    validations:\n      required: true\n\n  - type: textarea\n    id: document\n    attributes:\n      label: Document\n      description: |\n        **Required:** Attach the document or provide a link.\n        Drag and drop your file here, or paste a public URL.\n      placeholder: \"Drag and drop your document here, or paste a URL\"\n    validations:\n      required: true\n\n  - type: textarea\n    id: expected\n    attributes:\n      label: Expected Output\n      description: What did you expect the output to look like?\n      placeholder: \"I expected the table to have 3 columns with aligned text...\"\n    validations:\n      required: true\n\n  - type: textarea\n    id: actual\n    attributes:\n      label: Actual Output\n      description: What did you actually get? (paste relevant portions)\n      render: text\n    validations:\n      required: true\n\n  - type: textarea\n    id: command\n    attributes:\n      label: Command Used\n      description: The exact command or code you ran\n      render: bash\n      placeholder: \"lit parse document.pdf --format json\"\n    validations:\n      required: true\n\n  - type: input\n    id: version\n    attributes:\n      label: LiteParse Version\n      description: Run `lit --version` to get this\n      placeholder: \"0.1.0\"\n    validations:\n      required: true\n\n  - type: dropdown\n    id: os\n    attributes:\n      label: Operating System\n      options:\n        - macOS (Apple Silicon)\n        - macOS (Intel)\n        - Linux\n        - Windows\n        - Other\n    validations:\n      required: true\n\n  - type: textarea\n    id: additional\n    attributes:\n      label: Additional Context\n      description: Any other relevant information (OCR server used, config file, etc.)\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\n\non:\n  push:\n    branches: [main]\n  pull_request:\n    branches: [main]\n\njobs:\n  lint-and-build:\n    runs-on: ubuntu-latest\n\n    strategy:\n      matrix:\n        node-version: [18, 20, 22]\n\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n\n      - name: Setup Node.js ${{ matrix.node-version }}\n        uses: actions/setup-node@v4\n        with:\n          node-version: ${{ matrix.node-version }}\n          cache: \"npm\"\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Check formatting\n        run: npm run format:check\n\n      - name: Run linter\n        run: npm run lint\n\n      - name: Build\n        run: npm run build\n\n  test:\n    runs-on: ubuntu-latest\n\n    strategy:\n      matrix:\n        node-version: [18, 20, 22]\n\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n\n      - name: Setup Node.js ${{ matrix.node-version }}\n        uses: actions/setup-node@v4\n        with:\n          node-version: ${{ matrix.node-version }}\n          cache: \"npm\"\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Run tests\n        run: npm run test\n"
  },
  {
    "path": ".github/workflows/e2e-output.yml",
    "content": "name: E2E Output Validation\n\non:\n  pull_request:\n    branches: [main]\n  push:\n    branches: [main]\n\n# For PRs, we need write permissions to add labels\npermissions:\n  contents: read\n  pull-requests: write\n\njobs:\n  compare-outputs:\n    runs-on: ubuntu-latest\n    outputs:\n      has_changes: ${{ steps.compare.outputs.has_changes }}\n\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n\n      - name: Install system dependencies\n        run: |\n          sudo apt-get update\n          sudo apt-get install -y libreoffice imagemagick ghostscript tesseract-ocr\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: 20\n          cache: \"npm\"\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Build\n        run: npm run build\n\n      - name: Download from HuggingFace\n        env:\n          HF_TOKEN: ${{ secrets.HF_TOKEN }}\n        run: |\n          pip install huggingface_hub\n          hf download 'llamaindex/liteparse_cicd_data' --local-dir expected-dataset --repo-type dataset\n\n      - name: Compare outputs\n        id: compare\n        run: ./scripts/compare-outputs.sh expected-dataset\n\n      - name: Upload comparison results\n        if: always()\n        uses: actions/upload-artifact@v4\n        with:\n          name: comparison-results\n          path: comparison-output.txt\n\n      - name: Add label for changed outputs (PR only)\n        if: github.event_name == 'pull_request' && steps.compare.outputs.has_changes == 'true'\n        uses: actions/github-script@v7\n        with:\n          script: |\n            github.rest.issues.addLabels({\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              issue_number: context.issue.number,\n              labels: ['output-changed']\n            })\n\n      - name: Check for approval label (PR only)\n        id: check-approved\n        if: github.event_name == 'pull_request' && steps.compare.outputs.has_changes == 'true'\n        uses: actions/github-script@v7\n        with:\n          script: |\n            const { data: labels } = await github.rest.issues.listLabelsOnIssue({\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              issue_number: context.issue.number\n            });\n            const hasApproval = labels.some(label => label.name === 'output-approved');\n            core.setOutput('has_approval', hasApproval.toString());\n            console.log(`Has output-approved label: ${hasApproval}`);\n\n      - name: Require approval for output changes\n        if: steps.compare.outputs.has_changes == 'true' && github.event_name == 'pull_request' && steps.check-approved.outputs.has_approval != 'true'\n        run: |\n          echo \"::warning::This PR changes liteparse output. Please review the comparison results.\"\n          echo \"\"\n          echo \"To approve these changes:\"\n          echo \"1. Review the comparison output in the artifacts\"\n          echo \"2. Add the 'output-approved' label to this PR\"\n          echo \"3. Re-run this workflow\"\n          exit 1\n\n  # This job only runs on main branch after merge when outputs changed\n  upload-dataset:\n    runs-on: ubuntu-latest\n    needs: compare-outputs\n    if: github.event_name == 'push' && github.ref == 'refs/heads/main' && needs.compare-outputs.outputs.has_changes == 'true'\n\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n\n      - name: Install system dependencies\n        run: |\n          sudo apt-get update\n          sudo apt-get install -y libreoffice imagemagick ghostscript tesseract-ocr\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: 20\n          cache: \"npm\"\n\n      - name: Setup Python\n        uses: actions/setup-python@v5\n        with:\n          python-version: \"3.11\"\n\n      - name: Install dependencies\n        run: |\n          npm ci\n          pip install huggingface_hub\n\n      - name: Build\n        run: npm run build\n\n      - name: Download existing dataset from HuggingFace\n        env:\n          HF_TOKEN: ${{ secrets.HF_TOKEN }}\n        run: |\n          hf download 'llamaindex/liteparse_cicd_data' --local-dir expected-dataset --repo-type dataset\n\n      - name: Generate and upload dataset\n        env:\n          HF_TOKEN: ${{ secrets.HF_TOKEN }}\n        run: |\n          if [ -z \"$HF_TOKEN\" ]; then\n            echo \"Warning: HF_TOKEN not set, skipping upload\"\n            exit 0\n          fi\n          npx tsx scripts/upload-dataset.ts expected-dataset ${{ vars.HF_DATASET_REPO || 'llamaindex/liteparse_cicd_data' }}\n"
  },
  {
    "path": ".github/workflows/homebrew_release.yml",
    "content": "name: Push Release to HomeBrew repository\n\non:\n  workflow_dispatch:\n\njobs:\n  push-release-homebrew:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n        with:\n          fetch-depth: 0\n\n      - name: Install uv\n        uses: astral-sh/setup-uv@v6\n\n      - name: Set up Python\n        run: uv python install 3.13\n        shell: bash\n\n      - name: Push Release to HomeBrew repository\n        run: ./scripts/publish-to-homebrew-repo.sh\n        shell: bash\n        env:\n          GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_TOKEN }} # PAT with permissions to push to run-llama/homebrew-liteparse\n"
  },
  {
    "path": ".github/workflows/ocr_servers.yml",
    "content": "name: Validate OCR Servers\n\non:\n  pull_request:\n\njobs:\n  testing_paddleocr:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        python-version: [\"3.12\"]\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 1\n\n      - name: Install uv\n        uses: astral-sh/setup-uv@v6\n        with:\n          python-version: ${{ matrix.python-version }}\n          enable-cache: true\n\n      - name: Run Tests on Main Package\n        run: uv run pytest test_server.py\n        working-directory: ocr/paddleocr/\n\n  testing_easyocr:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        python-version: [\"3.12\"]\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 1\n\n      - name: Install uv\n        uses: astral-sh/setup-uv@v6\n        with:\n          python-version: ${{ matrix.python-version }}\n          enable-cache: true\n\n      - name: Run Tests on Main Package\n        run: uv run pytest test_server.py\n        working-directory: ocr/easyocr/\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Release\n\non:\n  push:\n    branches:\n      - main\n\nconcurrency: ${{ github.workflow }}-${{ github.ref }}\n\njobs:\n  release:\n    name: Release\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n      pull-requests: write\n      id-token: write\n      actions: write\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: 20\n          cache: \"npm\"\n          registry-url: \"https://registry.npmjs.org\"\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Build\n        run: npm run build\n\n      - name: Create Release Pull Request or Publish\n        id: changesets\n        uses: changesets/action@v1\n        with:\n          publish: npm run release\n          title: \"chore: version packages\"\n          commit: \"chore: version packages\"\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n\n      - name: Dispatch post-publish workflow\n        if: steps.changesets.outputs.published == 'true'\n        uses: actions/github-script@v7\n        with:\n          script: |\n            await github.rest.actions.createWorkflowDispatch({\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              workflow_id: 'homebrew_release.yml',\n              ref: 'main',\n            })\n"
  },
  {
    "path": ".github/workflows/sync-docs.yml",
    "content": "name: Sync Docs to Developer Hub\n\non:\n  push:\n    branches: [main]\n    paths:\n      - \"docs/**\"\n  workflow_dispatch:\n\njobs:\n  sync-docs:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout source repo\n        uses: actions/checkout@v4\n\n      - name: Install uv\n        uses: astral-sh/setup-uv@v4\n\n      - name: Checkout docs repo\n        uses: actions/checkout@v4\n        with:\n          repository: run-llama/developers\n          token: ${{ secrets.DEVELOPER_HUB_TOKEN }}\n          path: developer-hub\n\n      - name: Sync docs\n        run: |\n          npm install\n          npm run docs:api\n          ./scripts/sync-docs-to-developer-hub.sh developer-hub\n\n      - name: Commit and push\n        working-directory: developer-hub\n        run: |\n          git config user.name \"github-actions[bot]\"\n          git config user.email \"github-actions[bot]@users.noreply.github.com\"\n\n          git add src/content/docs/liteparse\n\n          if git diff --staged --quiet; then\n            echo \"No docs changes to sync.\"\n            exit 0\n          fi\n\n          SOURCE_SHA=\"${GITHUB_SHA::8}\"\n          git commit -m \"sync: liteparse docs from run-llama/liteparse@${SOURCE_SHA}\"\n          git push\n"
  },
  {
    "path": ".gitignore",
    "content": "# Dependencies\nnode_modules/\npnpm-lock.yaml\n\n# Build output\ndist/\nbin/\nsea-prep.blob\nsea-config.json\n\n# Environment\n*claude*\n.env\n.env.local\n\n# TypeScript\n*.tsbuildinfo\n\n# IDE\n.vscode/\n.idea/\n*.swp\n*.swo\n\n# OS\n.DS_Store\nThumbs.db\n\n# Logs\n*.log\nnpm-debug.log*\npnpm-debug.log*\n\n# Test output\nscreenshots/\n*.pdf\n!tests/fixtures/*.pdf\n\n# Temporary files\ntmp/\ntemp/\n*.txt\n*.png\ndeno.json\n\n# Python files\n*venv*\n__pycache__\n*.pyc\n*cache*\n\n# Test/dev directories (local testing)\ne2e-output/\nparsed_dataset/\nhard_docs/\nhard_docs_parsed/\ntest-docs/\ntest-docs-output/\narxiv_screenshots/\nmore_hard_docs/\nnytimes_imgs/\nac/\nltt/\n\n# OCR data files\n*.traineddata\n\n# Docs\n.docs-preview/\ndocs/src/content/docs/liteparse/api.md\ndocs/src/content/docs/liteparse/.api-tmp/\n"
  },
  {
    "path": ".prettierignore",
    "content": "dist\nnode_modules\nsrc/vendor\n*.md\npnpm-lock.yaml\npackage-lock.json\n"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"semi\": true,\n  \"singleQuote\": false,\n  \"tabWidth\": 2,\n  \"trailingComma\": \"es5\",\n  \"printWidth\": 100,\n  \"bracketSpacing\": true\n}\n"
  },
  {
    "path": "AGENTS.md",
    "content": "# LiteParse - Agent Documentation\n\n> This file provides comprehensive context for AI coding agents working on this codebase. Each subdirectory contains its own README with file-specific documentation.\n\n## Project Overview\n\n**LiteParse** is an open-source PDF parsing library focused on fast, lightweight document processing with spatial text extraction. It runs entirely locally with zero cloud dependencies by default.\n\n### Key Capabilities\n- **Spatial text extraction** with precise bounding boxes\n- **Flexible OCR** (built-in Tesseract.js or pluggable HTTP servers)\n- **Multi-format support** (PDFs, DOCX, XLSX, PPTX, images via conversion)\n- **TypeScript/Node.js** with both library and CLI interfaces\n\n## Directory Structure\n\n```\nliteparse/\n├── src/\n│   ├── core/           # Configuration, types, main orchestrator\n│   ├── engines/        # Pluggable PDF and OCR engines\n│   │   ├── pdf/        # PDF parsing engines (PDF.js, PDFium)\n│   │   └── ocr/        # OCR engines (Tesseract, HTTP)\n│   ├── processing/     # Text extraction and spatial analysis\n│   ├── output/         # Output formatters (JSON, text)\n│   ├── conversion/     # Multi-format conversion to PDF\n│   ├── vendor/         # Bundled dependencies (PDF.js)\n│   ├── index.ts        # CLI entry point\n│   └── lib.ts          # Library public API\n├── cli/                # CLI implementation\n├── ocr/                # Example OCR server implementations\n│   ├── easyocr/        # EasyOCR wrapper server\n│   └── paddleocr/      # PaddleOCR wrapper server\n└── dist/               # Compiled JavaScript output\n```\n\n## Data Flow\n\n1. **Input**: File path received (any supported format)\n2. **Conversion** (if dependencies installed): Non-PDF formats converted to PDF via LibreOffice/ImageMagick\n3. **PDF Loading**: PDF.js extracts text items, images, metadata\n4. **OCR** (if enabled): Images rendered and OCR'd for text-sparse areas\n5. **Grid Projection**: Spatial reconstruction of text layout using anchor system\n6. **Post-processing**: Bounding boxes, text cleanup\n7. **Output**: Formatted as JSON or plain text\n\n## Key Design Decisions\n\n### 1. Engine Abstraction Pattern\nBoth PDF and OCR functionality use interface-based abstraction (`PdfEngine`, `OcrEngine`). This allows:\n- Swapping implementations without changing core logic\n- Auto-detection: HTTP OCR if URL provided, otherwise Tesseract.js\n- Future extensibility for new engines\n- Future possibility of custom conversion engines for non-PDF formats\n\n### 2. Spatial Grid Projection\nThe most complex (and important!) part of the codebase (`src/processing/gridProjection.ts`, ~1650 lines). Uses:\n- **Anchor-based layout**: Tracks text alignment (left, right, center, floating)\n- **Forward anchors**: Carry alignment information between lines\n- **Column detection**: Identifies multi-column layouts\n- **Rotation handling**: Transforms 90°, 180°, 270° rotated text to correct reading order\n- **OCR merging**: Combines native PDF text with OCR results, preserving confidence scores and source flags in output\n\n### 3. Selective OCR\nOCR only runs on embedded images where text extraction failed, not the entire document. This balances accuracy with performance.\n\n### 4. Configuration Merging\nUses a default-first approach where users only override what they need. Configuration flows: defaults → file config → CLI options.\n\n### 5. Format Conversion via External Tools\nRather than implementing format parsers, LiteParse converts non-PDF formats using system tools (LibreOffice, ImageMagick) into a single format (PDF). This provides broad format support with minimal code.\n\n## Common Tasks\n\n### Adding a New Output Format\n1. Create new file in `src/output/` implementing the formatter\n2. Add format option to `cli/parse.ts`\n3. Update `src/core/parser.ts` to use new formatter\n\n### Adding a New OCR Engine\n1. Implement `OcrEngine` interface in `src/engines/ocr/`\n2. Add initialization logic in `src/core/parser.ts`\n3. Add configuration options in `src/core/types.ts`\n\n### Modifying Text Extraction Logic\nThe processing pipeline is in `src/processing/`. Key files:\n- `gridProjection.ts` - Layout reconstruction (most complex)\n- `bbox.ts` - Bounding box calculation\n- `cleanText.ts` - Text cleanup\n\n### Adding CLI Options\n1. Update `cli/parse.ts` with new Commander.js option\n2. Add corresponding config field in `src/core/types.ts`\n3. Update `src/core/config.ts` with default value\n4. Use the option in `src/core/parser.ts`\n\n## Testing Approach\n\nCurrently tested via manual verification with sample documents. The project would benefit from:\n- Unit tests for processing utilities\n- Integration tests with known PDFs\n- Snapshot tests for output formats\n\n## Key Dependencies\n\n| Dependency | Purpose |\n|------------|---------|\n| `pdfjs-dist` | PDF parsing and text extraction |\n| `@hyzyla/pdfium` | High-quality PDF rendering for screenshots |\n| `tesseract.js` | In-process OCR (zero setup) |\n| `sharp` | Image processing |\n| `commander` | CLI framework |\n| `zod` | Schema validation |\n\n## Entry Points\n\n- **CLI**: `src/index.ts` → `cli/parse.ts`\n- **Library**: `src/lib.ts` exports `LiteParse` class and types\n- **Main Class**: `src/core/parser.ts` contains `LiteParse` orchestrator\n\n## Related Documentation\n\nThese files are key to understanding the codebase and should be referenced for specific implementation details.\n\nIf changes to the codebase are being made, please update the relevant documentation files to reflect those changes and keep them up to date.\n\n- [User-facing documentation](README.md)\n- [src/conversion/README.md](src/conversion/README.md) - Format conversion details\n- [src/core/README.md](src/core/README.md) - Core architecture and configuration\n- [src/engines/README.md](src/engines/README.md) - Engine abstraction and implementations\n  - [src/engines/pdf/README.md](src/engines/pdf/README.md) - PDF engines (PDF.js, PDFium)\n  - [src/engines/ocr/README.md](src/engines/ocr/README.md) - OCR engines (Tesseract, HTTP)\n- [src/output/README.md](src/output/README.md) - Output formatters\n- [src/processing/README.md](src/processing/README.md) - Text extraction and spatial processing\n- [ocr/README.md](ocr/README.md) - OCR server implementations (EasyOCR, PaddleOCR)\n- [cli/README.md](cli/README.md) - CLI usage and options\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# @llamaindex/liteparse\n\n## 1.4.6\n\n### Patch Changes\n\n- [#120](https://github.com/run-llama/liteparse/pull/120) [`9cde441`](https://github.com/run-llama/liteparse/commit/9cde441b106b9dbee055b228bf011c197126bef5) Thanks [@apprakash](https://github.com/apprakash)! - fix(gridProjection): merge sub-pixel overlapping text runs in canMerge\n\n## 1.4.5\n\n### Patch Changes\n\n- [#118](https://github.com/run-llama/liteparse/pull/118) [`4fdf3c9`](https://github.com/run-llama/liteparse/commit/4fdf3c9358c22e50e742c2b7d866ae35b83a63cd) Thanks [@mkh09353](https://github.com/mkh09353)! - Honor the OCR rotation-correction option in the built-in Tesseract engine by mapping it to Tesseract.js auto-rotation.\n\n## 1.4.4\n\n### Patch Changes\n\n- [#112](https://github.com/run-llama/liteparse/pull/112) [`0eda8fc`](https://github.com/run-llama/liteparse/commit/0eda8fc27d6ad2cf835894efecc22c5239025447) Thanks [@logan-markewich](https://github.com/logan-markewich)! - Improve buggy-font handling resolution\n\n## 1.4.3\n\n### Patch Changes\n\n- [#108](https://github.com/run-llama/liteparse/pull/108) [`f4ee121`](https://github.com/run-llama/liteparse/commit/f4ee121d800b01f007a1d970d8197eda6673b392) Thanks [@Winds-AI](https://github.com/Winds-AI)! - Fix OCR bullet line spacing inflation\n\n## 1.4.2\n\n### Patch Changes\n\n- [#91](https://github.com/run-llama/liteparse/pull/91) [`5bb3a3b`](https://github.com/run-llama/liteparse/commit/5bb3a3b214b148bec86aaf979ea561611a7df763) Thanks [@AdemBoukhris457](https://github.com/AdemBoukhris457)! - fix: use path.join for screenshot output filepath\n\n- [#97](https://github.com/run-llama/liteparse/pull/97) [`1100bdb`](https://github.com/run-llama/liteparse/commit/1100bdbcb7293abb63d3eb38ff295669618265e0) Thanks [@AdemBoukhris457](https://github.com/AdemBoukhris457)! - fix: return null from extension detection for unrecognizable formats\n\n- [#89](https://github.com/run-llama/liteparse/pull/89) [`71f6621`](https://github.com/run-llama/liteparse/commit/71f6621dd413195b3634b747c6cf7cde90966035) Thanks [@AdemBoukhris457](https://github.com/AdemBoukhris457)! - perf: cache PDFium document across page operations\n\n- [#99](https://github.com/run-llama/liteparse/pull/99) [`b7a3080`](https://github.com/run-llama/liteparse/commit/b7a3080d89dccc4fd3cec65f559d4ebeff12e9bc) Thanks [@Winds-AI](https://github.com/Winds-AI)! - fix: validate ImageMagick executables before using convert\n\n- [#95](https://github.com/run-llama/liteparse/pull/95) [`2718912`](https://github.com/run-llama/liteparse/commit/2718912b520ffc475d8e2541f5430b0823bd0acd) Thanks [@AdemBoukhris457](https://github.com/AdemBoukhris457)! - fix: guard indexOf before splice in grid anchor resolution\n\n## 1.4.1\n\n### Patch Changes\n\n- [#84](https://github.com/run-llama/liteparse/pull/84) [`53e02df`](https://github.com/run-llama/liteparse/commit/53e02dff71d8f83cb2539b3a856889a5c3a38b52) Thanks [@AdemBoukhris457](https://github.com/AdemBoukhris457)! - Ensure parse cleans up temp files\n\n- [#86](https://github.com/run-llama/liteparse/pull/86) [`48d86f1`](https://github.com/run-llama/liteparse/commit/48d86f1f2a0fc9d0cad29d3d30476f5cd0844d85) Thanks [@AdemBoukhris457](https://github.com/AdemBoukhris457)! - Ensure screenshot converts formats when possible\n\n## 1.4.0\n\n### Minor Changes\n\n- [#64](https://github.com/run-llama/liteparse/pull/64) [`ab3df58`](https://github.com/run-llama/liteparse/commit/ab3df583fcbf6f0333a0649f7b4bd7331e5d547a) Thanks [@llrightll](https://github.com/llrightll)! - Add confidence scores to TextItems\n\n- [#71](https://github.com/run-llama/liteparse/pull/71) [`57adda1`](https://github.com/run-llama/liteparse/commit/57adda15e6a45832e7f3a1311fb475c7221c1dc8) Thanks [@saravananravi08](https://github.com/saravananravi08)! - Add internal image detection for OCR\n\n### Patch Changes\n\n- [#78](https://github.com/run-llama/liteparse/pull/78) [`d341371`](https://github.com/run-llama/liteparse/commit/d341371eae7c2fa8feb234af732cf30e978230b3) Thanks [@logan-markewich](https://github.com/logan-markewich)! - Improve searchItems output on complex text\n\n## 1.3.2\n\n### Patch Changes\n\n- [#55](https://github.com/run-llama/liteparse/pull/55) [`b57cb61`](https://github.com/run-llama/liteparse/commit/b57cb61de9371cbc1cf91f01aafc7e1fe912e520) Thanks [@hexapode](https://github.com/hexapode)! - Improve text projection on justified text\n\n## 1.3.1\n\n### Patch Changes\n\n- [#70](https://github.com/run-llama/liteparse/pull/70) [`243dc05`](https://github.com/run-llama/liteparse/commit/243dc0556769a59cf59e6565a5657b7d2630fc97) Thanks [@saravananravi08](https://github.com/saravananravi08)! - fix: resolve standard font loading failure in Node.js\n\n## 1.3.0\n\n### Minor Changes\n\n- [#67](https://github.com/run-llama/liteparse/pull/67) [`0542758`](https://github.com/run-llama/liteparse/commit/0542758f6239a1897d7553727ce3ec58c61ea7fe) Thanks [@logan-markewich](https://github.com/logan-markewich)! - Bbox utils and tesseract error handling\n\n## 1.2.0\n\n### Minor Changes\n\n- [#56](https://github.com/run-llama/liteparse/pull/56) [`31b43f9`](https://github.com/run-llama/liteparse/commit/31b43f9666ce6df85e90a44be1e859c615bda757) Thanks [@logan-markewich](https://github.com/logan-markewich)! - Add CLI Stdin support for files, urls, etc.\n\n## 1.1.0\n\n### Minor Changes\n\n- [#51](https://github.com/run-llama/liteparse/pull/51) [`7b421c6`](https://github.com/run-llama/liteparse/commit/7b421c61f2e2ffa04e68bb2bbe02dbf18e261507) Thanks [@logan-markewich](https://github.com/logan-markewich)! - Support for password protected PDFs\n\n## 1.0.1\n\n### Patch Changes\n\n- [#40](https://github.com/run-llama/liteparse/pull/40) [`bb863c4`](https://github.com/run-llama/liteparse/commit/bb863c46f568c5c192e7c6ec608e350303668bba) Thanks [@logan-markewich](https://github.com/logan-markewich)! - Add support for TESSDATA_PREFIX and better error messaging on tesseract network errors\n\n## 1.0.0\n\n### Major Changes\n\n- [#31](https://github.com/run-llama/liteparse/pull/31) [`56ba21c`](https://github.com/run-llama/liteparse/commit/56ba21cb63e8223440b039f49eab710ba089e375) Thanks [@logan-markewich](https://github.com/logan-markewich)! - LiteParse v1.0 launch\n"
  },
  {
    "path": "CLAUDE.md",
    "content": "@AGENTS.md"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to LiteParse\n\nThank you for your interest in contributing to LiteParse! This document provides guidelines and information for contributors.\n\n## Getting Started\n\n1. Fork the repository\n2. Clone your fork:\n   ```bash\n   git clone https://github.com/YOUR_USERNAME/liteparse.git\n   cd liteparse\n   ```\n3. Install dependencies:\n   ```bash\n   npm install\n   ```\n4. Build the project:\n   ```bash\n   npm run build\n   ```\n\n## What to Contribute?\n\nIn this project, we welcome a wide range of contributions, but we do want to maintain the spirit of the project. We are primarily focused on:\n\n- Core algorithms for PDF parsing and text extraction\n- OCR integrations and improvements\n- Different types or modifications to output formats\n\nWe are less interested in:\n\n- Markdown output\n- Any LLM integration or agent code\n- Anything that doesn't directly relate to improving the core parsing and extraction capabilities\n\nWhile the project is in Typescript today, I'm pretty open to porting to Rust if someone wanted to take that on as a contribution. The core algorithms and logic would be the same, just implemented in Rust instead of Typescript.\n\n## Development Workflow\n\n### Building\n\n```bash\nnpm run build      # Build TypeScript\nnpm run dev        # Watch mode for development\n```\n\n### Testing\n\n```bash\nnpm test           # Run tests\nnpm run test:watch # Run tests in watch mode\n```\n\n### Linting & Formatting\n\n```bash\nnpm run lint       # Check for linting issues\nnpm run lint:fix   # Fix linting issues\nnpm run format     # Format code with Prettier\n```\n\n### Testing Local Changes\n\nYou can test your changes locally:\n\n```bash\n# Parse a document\n./dist/src/index.js parse document.pdf\n\n# Generate screenshots\n./dist/src/index.js screenshot document.pdf -o ./screenshots\n```\n\n### Debugging Grid Projection\n\nWhen working on the grid projection algorithm (`src/processing/gridProjection.ts`), you can enable built-in debug logging and visual output instead of adding ad-hoc `console.log` statements.\n\n**Debug logging** traces every decision the projection makes — block detection, anchor extraction, snap assignment, rendering, and flowing text classification:\n\n```bash\n# Log all projection decisions to stderr\n./dist/src/index.js parse document.pdf --debug\n\n# Filter to a specific page\n./dist/src/index.js parse document.pdf --debug --debug-page 3\n\n# Filter to elements containing specific text\n./dist/src/index.js parse document.pdf --debug --debug-text-filter \"Total\" \"Revenue\"\n\n# Filter to a bounding region (x1,y1,x2,y2 in PDF points)\n./dist/src/index.js parse document.pdf --debug --debug-region \"0,100,300,200\"\n\n# Write debug log to a file\n./dist/src/index.js parse document.pdf --debug --debug-output ./debug-output\n```\n\n**Visual grid export** generates PNG images showing text boxes color-coded by snap type (blue=left, red=right, green=center, gray=floating, yellow=flowing) with anchor lines overlaid. This is useful for comparing against page screenshots to spot projection issues:\n\n```bash\n# Generate visualization PNGs (one per page)\n./dist/src/index.js parse document.pdf --debug-visualize\n\n# Specify output directory\n./dist/src/index.js parse document.pdf --debug-visualize --debug-output ./my-debug\n```\n\nThese options are also available via the library API:\n\n```typescript\nconst parser = new LiteParse({\n  debug: {\n    enabled: true,\n    textFilter: [\"Total\"],\n    pageFilter: 2,\n    visualize: true,\n    visualizePath: \"./debug-output\",\n  }\n});\n```\n\nSee `src/processing/gridDebugLogger.ts` for the full `GridDebugConfig` interface and `src/processing/gridVisualizer.ts` for the visualization renderer.\n\n## Making Changes\n\n### Versioning & Changelogs\n\nWe use [Changesets](https://github.com/changesets/changesets) to manage versioning and changelogs. When you make a change to source code that should be released:\n\n1. Run `npm run changeset`\n2. Select the type of change (patch, minor, major)\n3. Write a description of your changes\n4. Commit the generated changeset file with your PR\n\n## Pull Requests\n\n1. Fork and create a feature branch from `main`\n2. Make your changes\n3. Add a changeset if needed (`npm run changeset`)\n4. Ensure all tests pass (`npm test`)\n5. Ensure linting passes (`npm run lint:fix` and `npm run format`)\n6. Submit a pull request\n\nWhen you submit a PR, a number of CICD checks will run. Among these, your code will be tested against a regression suite of documents to ensure that your changes don't break existing parsing capabilities. It will be up to the maintainers discretion to determine if any changes to the regression set are expected/positive or unexpected/negative.\n\n### PR Guidelines\n\n- Keep PRs focused on a single change\n- Update documentation if needed\n- Add tests for new functionality\n- For parsing issues, include a test document if possible\n\n## Reporting Issues\n\n### Parsing Issues\n\nIf you're reporting a problem with document parsing:\n\n1. **You must attach the document** or provide a way to reproduce the issue\n2. Include the command you ran\n3. Show the expected vs actual output\n4. Include your LiteParse version (`lit --version`)\n\nIssues without reproducible examples will be closed.\n\n### Bug Reports\n\nFor other bugs:\n1. Describe what you expected vs what happened\n2. Include steps to reproduce\n3. Include error messages/stack traces\n4. Include version information\n\n## Project Structure\n\nSee [AGENTS.md](AGENTS.md) for detailed documentation about the codebase structure and architecture.\n\nKey directories:\n- `src/core/` - Main orchestrator and configuration\n- `src/engines/` - PDF and OCR engine implementations\n- `src/processing/` - Text extraction and spatial analysis\n- `src/output/` - Output formatters\n- `cli/` - CLI implementation\n\n## Questions?\n\n- Open a [Discussion](https://github.com/run-llama/liteparse/discussions) for questions\n- Check existing issues before opening new ones\n- Read the [README](README.md) for usage documentation\n\n## License\n\nBy contributing, you agree that your contributions will be licensed under the Apache 2.0 License.\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "OCR_API_SPEC.md",
    "content": "# LiteParse OCR API Specification\n\nThis document defines the standard HTTP API that OCR servers must implement to work with LiteParse.\n\n## Overview\n\nLiteParse expects a simple HTTP endpoint that accepts an image and returns text with bounding boxes. Your OCR server can internally use any OCR engine (EasyOCR, PaddleOCR, Tesseract, Cloud APIs, etc.) as long as it conforms to this API.\n\n## Endpoint\n\n```\nPOST /ocr\n```\n\n## Request Format\n\n**Content-Type:** `multipart/form-data`\n\n**Fields:**\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `file` | binary | Yes | Image file (PNG, JPG, etc.) |\n| `language` | string | No | Language code (default: `en`) |\n\n### Language Codes\n\nUse ISO 639-1 two-letter codes:\n- `en` - English\n- `zh` - Chinese\n- `ja` - Japanese\n- `ko` - Korean\n- `fr` - French\n- `de` - German\n- `es` - Spanish\n- `ar` - Arabic\n- etc.\n\nYour server should map these to whatever format your underlying OCR engine expects.\n\n## Response Format\n\n**Content-Type:** `application/json`\n\n**Structure:**\n\n```json\n{\n  \"results\": [\n    {\n      \"text\": \"recognized text\",\n      \"bbox\": [x1, y1, x2, y2],\n      \"confidence\": 0.95\n    }\n  ]\n}\n```\n\n**Fields:**\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `results` | array | Array of text detection results |\n| `results[].text` | string | Recognized text content |\n| `results[].bbox` | [number, number, number, number] | Bounding box `[x1, y1, x2, y2]` where (x1,y1) is top-left and (x2,y2) is bottom-right |\n| `results[].confidence` | number | Confidence score between 0.0 and 1.0 |\n\n## Example\n\n### Request\n\n```bash\ncurl -X POST http://localhost:8080/ocr \\\n  -F \"file=@document.png\" \\\n  -F \"language=en\"\n```\n\n### Response\n\n```json\n{\n  \"results\": [\n    {\n      \"text\": \"Hello\",\n      \"bbox\": [10, 20, 60, 40],\n      \"confidence\": 0.98\n    },\n    {\n      \"text\": \"World\",\n      \"bbox\": [70, 20, 130, 40],\n      \"confidence\": 0.97\n    }\n  ]\n}\n```\n\n## Error Handling\n\nReturn appropriate HTTP status codes:\n\n- `200 OK` - Success\n- `400 Bad Request` - Invalid request (missing file, invalid language, etc.)\n- `500 Internal Server Error` - OCR processing failed\n\nError response format:\n\n```json\n{\n  \"error\": \"Description of the error\"\n}\n```\n\n## Implementation Notes\n\n### Coordinate System\n\n- Origin (0,0) is at the **top-left** of the image\n- X increases to the right\n- Y increases downward\n- All coordinates are in pixels\n\n### Bounding Box Format\n\nAlways return axis-aligned bounding boxes as `[x1, y1, x2, y2]`:\n- `x1, y1` = top-left corner\n- `x2, y2` = bottom-right corner\n- `x2 > x1` and `y2 > y1`\n\nIf your OCR engine returns rotated boxes or polygon coordinates, convert them to axis-aligned boxes by taking min/max coordinates.\n\n### Confidence Scores\n\n- Normalize to range 0.0 to 1.0\n- 1.0 = 100% confident\n- 0.0 = 0% confident\n- If your OCR engine doesn't provide confidence, use `1.0`\n\n### Text Ordering\n\nResults should be ordered by reading order (top-to-bottom, left-to-right for most languages).\n\n## Example Implementations\n\nSee the `/ocr` directory for reference implementations:\n\n- `ocr/easyocr/` - Wrapper for EasyOCR\n- `ocr/paddleocr/` - Wrapper for PaddleOCR\n\n## Testing Your Server\n\nQuick test:\n\n```bash\n# 1. Start your server\npython server.py\n\n# 2. Test with curl\ncurl -X POST http://localhost:8080/ocr \\\n  -F \"file=@test.png\" \\\n  -F \"language=en\" \\\n  | jq .\n\n# 3. Expected output:\n# {\n#   \"results\": [\n#     {\n#       \"text\": \"...\",\n#       \"bbox\": [x1, y1, x2, y2],\n#       \"confidence\": 0.xx\n#     }\n#   ]\n# }\n```\n\nUse with LiteParse:\n\n```bash\nlit parse document.pdf --ocr-server-url http://localhost:8080/ocr\n```\n\n## FAQ\n\n### Q: What if my OCR returns rotated bounding boxes?\n\nConvert to axis-aligned boxes:\n\n```python\ndef polygon_to_bbox(polygon):\n    \"\"\"Convert polygon [[x1,y1], [x2,y2], ...] to [x1, y1, x2, y2]\"\"\"\n    xs = [point[0] for point in polygon]\n    ys = [point[1] for point in polygon]\n    return [min(xs), min(ys), max(xs), max(ys)]\n```\n\n### Q: What if my OCR doesn't return confidence scores?\n\nJust return `1.0` for all results.\n\n### Q: Can I return empty results?\n\nYes, return `{\"results\": []}` if no text is detected.\n\n### Q: Should I filter low-confidence results?\n\nYou can, but LiteParse will also handle filtering based on its own thresholds.\n\n### Q: What image formats should I accept?\n\nAt minimum: PNG, JPG. Optionally: TIFF, WebP, BMP, GIF.\n\n### Q: Should I handle rotation correction?\n\nOptional. If your OCR engine supports it, you can auto-correct rotation before processing.\n\n### Q: What about multi-page documents?\n\nLiteParse handles page splitting. Your server only needs to process single images.\n\n### Q: Performance considerations?\n\n- Keep server response time under 10 seconds per image\n- Support concurrent requests\n- Consider GPU acceleration for better performance\n- Cache OCR models in memory (don't reload per request)\n\n## Compliance Checklist\n\n- [ ] Accepts `POST /ocr` endpoint\n- [ ] Accepts `file` and `language` form fields\n- [ ] Returns JSON with `results` array\n- [ ] Each result has `text`, `bbox`, and `confidence`\n- [ ] Bounding boxes in `[x1, y1, x2, y2]` format\n- [ ] Confidence normalized to 0.0-1.0 range\n- [ ] Returns 200 status on success\n- [ ] Returns appropriate error codes and messages\n- [ ] Handles common image formats (PNG, JPG)\n- [ ] Processes images in under 10 seconds\n\n## Support\n\nQuestions? Open an issue on GitHub or refer to the example implementations in `/ocr`.\n"
  },
  {
    "path": "README.md",
    "content": "# LiteParse\n\n[![CI](https://github.com/run-llama/liteparse/actions/workflows/ci.yml/badge.svg)](https://github.com/run-llama/liteparse/actions/workflows/ci.yml)\n|\n[![npm version](https://img.shields.io/npm/v/@llamaindex/liteparse.svg)](https://www.npmjs.com/package/@llamaindex/liteparse)\n|\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n|\n[Docs](https://developers.llamaindex.ai/liteparse/)\n\n<img src=\"https://github.com/user-attachments/assets/07ba6a82-6bb1-4dea-b0ef-cad7df7d1622\" alt=\"out\" width=\"600\">\n\nLiteParse is a standalone OSS PDF parsing tool focused exclusively on **fast and light** parsing. It provides high-quality spatial text parsing with bounding boxes, without proprietary LLM features or cloud dependencies. Everything runs locally on your machine. \n\n**Hitting the limits of local parsing?**\nFor complex documents (dense tables, multi-column layouts, charts, handwritten text, or \nscanned PDFs), you'll get significantly better results with [LlamaParse](https://developers.llamaindex.ai/python/cloud/llamaparse/?utm_source=github&utm_medium=liteparse), \nour cloud-based document parser built for production document pipelines. LlamaParse handles the \nhard stuff so your models see clean, structured data and markdown.\n\n>  👉 [Sign up for LlamaParse free](https://cloud.llamaindex.ai?utm_source=github&utm_medium=liteparse)\n\n## Overview\n\n- **Fast Text Parsing**: Spatial text parsing using PDF.js\n- **Flexible OCR System**:\n  - **Built-in**: Tesseract.js (zero setup, works out of the box!)\n  - **HTTP Servers**: Plug in any OCR server (EasyOCR, PaddleOCR, custom)\n  - **Standard API**: Simple, well-defined OCR API specification\n- **Screenshot Generation**: Generate high-quality page screenshots for LLM agents\n- **Multiple Output Formats**: JSON and Text\n- **Bounding Boxes**: Precise text positioning information\n- **Standalone Binary**: No cloud dependencies, runs entirely locally\n- **Multi-platform**: Linux, macOS (Intel/ARM), Windows\n\n## Installation\n\n### CLI Tool\n\n#### Option 1: Global Install (Recommended)\n\nInstall globally via npm to use the `lit` command anywhere:\n\n```bash\nnpm i -g @llamaindex/liteparse\n```\n\nThen use it:\n\n```bash\nlit parse document.pdf\nlit screenshot document.pdf\n```\n\nFor macOS and Linux users, `liteparse` can be also installed via `brew`:\n\n```bash\nbrew tap run-llama/liteparse\nbrew install llamaindex-liteparse\n```\n\n#### Option 2: Install from Source\n\nYou can clone the repo and install the CLI globally from source:\n\n```\ngit clone https://github.com/run-llama/liteparse.git\ncd liteparse\nnpm run build\nnpm pack\nnpm install -g ./liteparse-*.tgz\n```\n\n### Agent Skill\n\nYou can use `liteparse` as an agent skill, downloading it with the `skills` CLI tool:\n\n```bash\nnpx skills add run-llama/llamaparse-agent-skills --skill liteparse\n```\n\nOr copy-pasting the [`SKILL.md`](https://github.com/run-llama/llamaparse-agent-skills/blob/main/skills/liteparse/SKILL.md) file to your own skills setup.\n\n## Usage\n\n### Parse Files\n\n```bash\n# Basic parsing\nlit parse document.pdf\n\n# Parse with specific format\nlit parse document.pdf --format json -o output.md\n\n# Parse specific pages\nlit parse document.pdf --target-pages \"1-5,10,15-20\"\n\n# Parse without OCR\nlit parse document.pdf --no-ocr\n\n# Parse a remote PDF\ncurl -sL https://example.com/report.pdf | lit parse -\n```\n\n### Batch Parsing\n\nYou can also parse an entire directory of documents:\n\n```bash\nlit batch-parse ./input-directory ./output-directory\n```\n\n### Generate Screenshots\n\nScreenshots are essential for LLM agents to extract visual information that text alone cannot capture.\n\n```bash\n# Screenshot all pages\nlit screenshot document.pdf -o ./screenshots\n\n# Screenshot specific pages\nlit screenshot document.pdf --target-pages \"1,3,5\" -o ./screenshots\n\n# Custom DPI\nlit screenshot document.pdf --dpi 300 -o ./screenshots\n\n# Screenshot page range\nlit screenshot document.pdf --target-pages \"1-10\" -o ./screenshots\n```\n\n### Library Usage\n\nInstall as a dependency in your project:\n\n```bash\nnpm install @llamaindex/liteparse\n# or\npnpm add @llamaindex/liteparse\n```\n\n```typescript\nimport { LiteParse } from '@llamaindex/liteparse';\n\nconst parser = new LiteParse({ ocrEnabled: true });\nconst result = await parser.parse('document.pdf');\nconsole.log(result.text);\n```\n\n#### Buffer / Uint8Array Input\n\nYou can pass raw bytes directly instead of a file path, which is useful for remote files:\n\n```typescript\nimport { LiteParse } from '@llamaindex/liteparse';\nimport { readFile } from 'fs/promises';\n\nconst parser = new LiteParse();\n\n// From a file read\nconst pdfBytes = await readFile('document.pdf');\nconst result = await parser.parse(pdfBytes);\n\n// From an HTTP response\nconst response = await fetch('https://example.com/document.pdf');\nconst buffer = Buffer.from(await response.arrayBuffer());\nconst result2 = await parser.parse(buffer);\n```\n\nNon-PDF buffers (images, Office documents) are written to a temp directory for format conversion. Screenshots also work with buffer input:\n\n```typescript\nconst screenshots = await parser.screenshot(pdfBytes, [1, 2, 3]);\n```\n\n### CLI Options\n\n#### Parse Command\n\n```\n$ lit parse --help\nUsage: lit parse [options] <file>\n\nParse a document file (PDF, DOCX, XLSX, PPTX, images, etc.)\n\nOptions:\n  -o, --output <file>     Output file path\n  --format <format>       Output format: json|text (default: \"text\")\n  --ocr-server-url <url>  HTTP OCR server URL (uses Tesseract if not provided)\n  --no-ocr                Disable OCR\n  --ocr-language <lang>   OCR language(s) (default: \"en\")\n  --num-workers <n>       Number of pages to OCR in parallel (default: CPU cores - 1)\n  --max-pages <n>         Max pages to parse (default: \"10000\")\n  --target-pages <pages>  Target pages (e.g., \"1-5,10,15-20\")\n  --dpi <dpi>             DPI for rendering (default: \"150\")\n  --no-precise-bbox       Disable precise bounding boxes\n  --preserve-small-text   Preserve very small text\n  --password <password>   Password for encrypted/protected documents\n  --config <file>         Config file (JSON)\n  -q, --quiet             Suppress progress output\n  -h, --help              display help for command\n```\n\n#### Batch Parse Command\n\n```\n$ lit batch-parse --help\nUsage: lit batch-parse [options] <input-dir> <output-dir>\n\nParse multiple documents in batch mode (reuses PDF engine for efficiency)\n\nOptions:\n  --format <format>       Output format: json|text (default: \"text\")\n  --ocr-server-url <url>  HTTP OCR server URL (uses Tesseract if not provided)\n  --no-ocr                Disable OCR\n  --ocr-language <lang>   OCR language(s) (default: \"en\")\n  --num-workers <n>       Number of pages to OCR in parallel (default: CPU cores - 1)\n  --max-pages <n>         Max pages to parse per file (default: \"10000\")\n  --dpi <dpi>             DPI for rendering (default: \"150\")\n  --no-precise-bbox       Disable precise bounding boxes\n  --recursive             Recursively search input directory\n  --extension <ext>       Only process files with this extension (e.g., \".pdf\")\n  --password <password>   Password for encrypted/protected documents (applied to all files)\n  --config <file>         Config file (JSON)\n  -q, --quiet             Suppress progress output\n  -h, --help              display help for command\n```\n\n#### Screenshot Command\n\n```\n$ lit screenshot --help\nUsage: lit screenshot [options] <file>\n\nGenerate screenshots of PDF pages\n\nOptions:\n  -o, --output-dir <dir>  Output directory for screenshots (default: \"./screenshots\")\n  --target-pages <pages>  Page numbers to screenshot (e.g., \"1,3,5\" or \"1-5\")\n  --dpi <dpi>             DPI for rendering (default: \"150\")\n  --format <format>       Image format: png|jpg (default: \"png\")\n  --password <password>   Password for encrypted/protected documents\n  --config <file>         Config file (JSON)\n  -q, --quiet             Suppress progress output\n  -h, --help              display help for command\n```\n\n## OCR Setup\n\n### Default: Tesseract.js\n\n```bash\n# Tesseract is enabled by default\nlit parse document.pdf\n\n# Specify language\nlit parse document.pdf --ocr-language fra\n\n# Disable OCR\nlit parse document.pdf --no-ocr\n```\n\nBy default, Tesseract.js downloads language data from the internet on first use. For offline or air-gapped environments, set the `TESSDATA_PREFIX` environment variable to a directory containing pre-downloaded `.traineddata` files:\n\n```bash\nexport TESSDATA_PREFIX=/path/to/tessdata\nlit parse document.pdf --ocr-language eng\n```\n\nYou can also pass `tessdataPath` in the library config:\n\n```typescript\nconst parser = new LiteParse({ tessdataPath: '/path/to/tessdata' });\n```\n\n### Optional: HTTP OCR Servers\n\nFor higher accuracy or better performance, you can use an HTTP OCR server. We provide ready-to-use example wrappers for popular OCR engines:\n\n- [EasyOCR](ocr/easyocr/README.md)\n- [PaddleOCR](ocr/paddleocr/README.md)\n\nYou can integrate any OCR service by implementing the simple LiteParse OCR API specification (see [`OCR_API_SPEC.md`](OCR_API_SPEC.md)).\n\nThe API requires:\n- POST `/ocr` endpoint\n- Accepts `file` and `language` parameters\n- Returns JSON: `{ results: [{ text, bbox: [x1,y1,x2,y2], confidence }] }`\n\nSee the example servers in `ocr/easyocr/` and `ocr/paddleocr/` as templates.\n\nFor the complete OCR API specification, see [`OCR_API_SPEC.md`](OCR_API_SPEC.md).\n\n## Multi-Format Input Support\n\nLiteParse supports **automatic conversion** of various document formats to PDF before parsing. This makes it unique compared to other PDF-only parsing tools!\n\n### Supported Input Formats\n\n#### Office Documents (via LibreOffice)\n- **Word**: `.doc`, `.docx`, `.docm`, `.odt`, `.rtf`\n- **PowerPoint**: `.ppt`, `.pptx`, `.pptm`, `.odp`\n- **Spreadsheets**: `.xls`, `.xlsx`, `.xlsm`, `.ods`, `.csv`, `.tsv`\n\nJust install the dependency and LiteParse will automatically convert these formats to PDF for parsing:\n\n```bash\n# macOS\nbrew install --cask libreoffice\n\n# Ubuntu/Debian\napt-get install libreoffice\n\n# Windows\nchoco install libreoffice-fresh # might require admin permissions\n```\n\n> _For Windows, you might need to add the path to the directory containing LibreOffice CLI executable (generally `C:\\Program Files\\LibreOffice\\program`) to the environment variables and re-start the machine._\n\n#### Images (via ImageMagick)\n- **Formats**: `.jpg`, `.jpeg`, `.png`, `.gif`, `.bmp`, `.tiff`, `.webp`, `.svg`\n\nJust install ImageMagick and LiteParse will convert images to PDF for parsing (with OCR):\n\n```bash\n# macOS\nbrew install imagemagick\n\n# Ubuntu/Debian\napt-get install imagemagick\n\n# Windows\nchoco install imagemagick.app # might require admin permissions\n```\n\n## Environment Variables\n\n| Variable | Description |\n|----------|-------------|\n| `TESSDATA_PREFIX` | Path to a directory containing Tesseract `.traineddata` files. Used for offline/air-gapped environments where Tesseract.js cannot download language data from the internet. |\n| `LITEPARSE_TMPDIR` | Override the temp directory used for format conversion and intermediate files. Defaults to the OS temp directory (`os.tmpdir()`). Useful in containerized or read-only filesystem environments. |\n\n## Configuration\n\nYou can configure parsing options via CLI flags or a JSON config file. The config file allows you to set sensible defaults and override as needed.\n\n### Config File Example\n\nCreate a `liteparse.config.json` file:\n\n```json\n{\n  \"ocrLanguage\": \"en\",\n  \"ocrEnabled\": true,\n  \"maxPages\": 1000,\n  \"dpi\": 150,\n  \"outputFormat\": \"json\",\n  \"preciseBoundingBox\": true,\n  \"preserveVerySmallText\": false,\n  \"password\": \"optional_password\"\n}\n```\n\nFor HTTP OCR servers, just add `ocrServerUrl`:\n\n```json\n{\n  \"ocrServerUrl\": \"http://localhost:8828/ocr\",\n  \"ocrLanguage\": \"en\",\n  \"outputFormat\": \"json\"\n}\n```\n\nUse with:\n\n```bash\nlit parse document.pdf --config liteparse.config.json\n```\n\n## Development\n\nWe provide a fairly rich `AGENTS.md`/`CLAUDE.md` that we recommend using to help with development + coding agents.\n\n```bash\n# Install dependencies\nnpm install\n\n# Build TypeScript (Linux/macOs)\nnpm run build\n\n# Build Typescript (Windows)\nnpm run build:windows\n\n# Watch mode\nnpm run dev\n\n# Test parsing\nnpm test\n```\n\n## License\n\nApache 2.0\n\n## Credits\n\nBuilt on top of:\n\n- [PDF.js](https://github.com/mozilla/pdf.js) - PDF parsing engine\n- [Tesseract.js](https://github.com/naptha/tesseract.js) - In-process OCR engine\n- [EasyOCR](https://github.com/JaidedAI/EasyOCR) - HTTP OCR server (optional)\n- [PaddleOCR](https://github.com/PaddlePaddle/PaddleOCR) - HTTP OCR server (optional)\n- [Sharp](https://github.com/lovell/sharp) - Image processing\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\n## Reporting a Vulnerability\n\nIf you discover a security vulnerability in LiteParse, please report it responsibly:\n\n1. **Do NOT open a public issue** for security vulnerabilities\n2. Email security concerns to: security@llamaindex.ai\n3. Include as much detail as possible:\n   - Description of the vulnerability\n   - Steps to reproduce\n   - Potential impact\n   - Suggested fix (if any)\n\n## Scope\n\n### In Scope\n\nSecurity issues we will address:\n\n- Remote code execution in the CLI tool or library\n- Vulnerabilities in LiteParse's own code that could be exploited\n- Dependency vulnerabilities with known, exploitable CVEs\n\n### Out of Scope\n\nLiteParse is intended to be a local CLI tool and library, designed to process documents you provide. The following are not security vulnerabilities we will address:\n\n- **Malicious input files** - Processing untrusted documents (zip bombs, malformed PDFs, path traversal in filenames, etc.) is the user's responsibility. If you're building a service that accepts untrusted uploads, you must implement your own validation, sandboxing, and resource limits.\n- **Denial of service via large/complex files** - Documents that cause high memory usage, long processing times, or crashes are not security issues. Use `--max-pages`, timeouts, and resource limits in your deployment.\n- **Issues requiring a server setup** - LiteParse does not include or recommend any specific production server deployment. Security of web services built on top of LiteParse is the deployer's responsibility.\n- **Theoretical attacks without proof of concept** - Please include a working demonstration.\n\n### Building Secure Services\n\nIf you're exposing LiteParse through a web service or API:\n\n1. Validate uploads:  Check file types, sizes, and origins before processing\n2. Use sandboxing:  Run parsing in isolated containers with resource limits\n3. Set timeouts:  Don't allow unbounded processing time\n4. Limit concurrency:  Prevent resource exhaustion from parallel requests\n5. Don't trust filenames:  Sanitize any paths derived from user input\n\nThese concerns are standard for any document processing service and are outside LiteParse's scope.\n"
  },
  {
    "path": "cli/README.md",
    "content": "# cli/\n\nCommand-line interface for LiteParse using Commander.js.\n\n## Files\n\n### parse.ts\n**CLI entry point with two main commands: `parse` and `screenshot`.**\n\n---\n\n## Commands\n\n### `lit parse <file>`\n\nParse documents and extract text.\n\n---\n\n### `lit screenshot <file> -o <output_dir>`\n\nGenerate page screenshots.\n\n---\n\n## Configuration File\n\nBoth commands accept `--config <file>` to load settings from JSON:\n\n```json\n{\n  \"ocrEnabled\": true,\n  \"ocrLanguage\": \"en\",\n  \"ocrServerUrl\": \"http://localhost:5000/ocr\",\n  \"maxPages\": 100,\n  \"dpi\": 200,\n  \"outputFormat\": \"json\",\n  \"preciseBoundingBox\": true,\n  \"password\": \"optional_password\"\n}\n```\n\nCLI options override config file values.\n\n---\n\n## Adding CLI Options\n\n1. Add `.option()` call in the command definition\n2. Read option in action handler from `options` object\n3. Add to config object that's passed to `LiteParse`\n4. If new config field, update `src/core/types.ts` and `src/core/config.ts`\n"
  },
  {
    "path": "cli/parse.ts",
    "content": "import { Command, Option } from \"commander\";\nimport fs from \"fs/promises\";\nimport { existsSync, readdirSync, statSync } from \"fs\";\nimport os from \"os\";\nimport path from \"path\";\nimport { LiteParse } from \"../src/core/parser.js\";\nimport { LiteParseConfig, OutputFormat } from \"../src/core/types.js\";\nimport { performance } from \"perf_hooks\";\n\nconst DEFAULT_MAX_PAGES = 10000;\nconst DEFAULT_DPI = 150;\nconst DEFAULT_LANGUAGE = \"en\";\nconst DEFAULT_OUTPUT_FORMAT = \"text\";\nconst DEFAULT_SCREENSHOT_FORMAT = \"png\";\nconst DEFAULT_SCREENSHOT_DIR = \"./screenshots\";\n\ninterface ParseCommandOptions {\n  output?: string;\n  format?: string;\n  ocrServerUrl?: string;\n  ocr?: boolean;\n  ocrLanguage?: string;\n  numWorkers?: string;\n  maxPages?: string;\n  targetPages?: string;\n  dpi?: string;\n  preciseBbox?: boolean;\n  preserveSmallText?: boolean;\n  password?: string;\n  config?: string;\n  quiet?: boolean;\n  debug?: boolean;\n  debugVisualize?: boolean;\n  debugOutput?: string;\n  debugTextFilter?: string[];\n  debugPage?: string;\n  debugRegion?: string;\n}\n\ninterface ScreenshotCommandOptions {\n  outputDir?: string;\n  targetPages?: string;\n  dpi?: string;\n  format?: string;\n  password?: string;\n  config?: string;\n  quiet?: boolean;\n}\n\ninterface BatchParseCommandOptions {\n  format?: string;\n  ocrServerUrl?: string;\n  ocr?: boolean;\n  ocrLanguage?: string;\n  numWorkers?: string;\n  maxPages?: string;\n  dpi?: string;\n  preciseBbox?: boolean;\n  recursive?: boolean;\n  extension?: string;\n  password?: string;\n  config?: string;\n  quiet?: boolean;\n}\n\nconst program = new Command();\n\nprogram\n  .name(\"lit\")\n  .description(\"OSS document parsing tool (supports PDF, DOCX, XLSX, images, and more)\")\n  .version(\"0.1.0\");\n\nprogram\n  .command(\"parse <file>\")\n  .description(\"Parse a document file (PDF, DOCX, XLSX, PPTX, images, etc.)\")\n  .option(\"-o, --output <file>\", \"Output file path\")\n  .option(\"--format <format>\", \"Output format: json|text\", DEFAULT_OUTPUT_FORMAT)\n  .option(\"--ocr-server-url <url>\", \"HTTP OCR server URL (uses Tesseract if not provided)\")\n  .option(\"--no-ocr\", \"Disable OCR\")\n  .option(\"--ocr-language <lang>\", \"OCR language(s)\", DEFAULT_LANGUAGE)\n  .option(\n    \"--num-workers <n>\",\n    \"Number of pages to OCR in parallel. Defaults to number of CPU cores minus one.\"\n  )\n  .option(\"--max-pages <n>\", \"Max pages to parse\", DEFAULT_MAX_PAGES.toString())\n  .option(\"--target-pages <pages>\", 'Target pages (e.g., \"1-5,10,15-20\")')\n  .option(\"--dpi <dpi>\", \"DPI for rendering\", DEFAULT_DPI.toString())\n  .option(\"--no-precise-bbox\", \"Disable precise bounding boxes\")\n  .option(\"--preserve-small-text\", \"Preserve very small text\")\n  .option(\"--password <password>\", \"Password for encrypted/protected documents\")\n  .option(\"--config <file>\", \"Config file (JSON)\")\n  .option(\"-q, --quiet\", \"Suppress progress output\")\n  .addOption(new Option(\"--debug\", \"Enable grid projection debug logging\").hideHelp())\n  .addOption(new Option(\"--debug-visualize\", \"Generate grid visualization PNGs\").hideHelp())\n  .addOption(new Option(\"--debug-output <path>\", \"Output directory for debug files\").hideHelp())\n  .addOption(\n    new Option(\"--debug-text-filter <texts...>\", \"Filter debug output by text content\").hideHelp()\n  )\n  .addOption(\n    new Option(\"--debug-page <num>\", \"Filter debug output to specific page number\").hideHelp()\n  )\n  .addOption(\n    new Option(\"--debug-region <coords>\", 'Filter to bounding region \"x1,y1,x2,y2\"').hideHelp()\n  )\n  .action(async (file: string, options: ParseCommandOptions) => {\n    try {\n      const quiet = options.quiet || false;\n      const isStdin = file === \"-\";\n\n      // Check if file exists (skip for stdin)\n      if (!isStdin && !existsSync(file)) {\n        console.error(`Error: File not found: ${file}`);\n        process.exit(1);\n      }\n\n      let config: Partial<LiteParseConfig> = {};\n\n      // Load config file if provided\n      if (options.config) {\n        if (!existsSync(options.config)) {\n          console.error(`Error: Config file not found: ${options.config}`);\n          process.exit(1);\n        }\n        const configData = await fs.readFile(options.config, \"utf-8\");\n        config = JSON.parse(configData);\n      }\n\n      // Override with CLI options\n      let calculatedNumWorkers = os.cpus().length - 1;\n      if (calculatedNumWorkers < 1) {\n        calculatedNumWorkers = 1;\n      }\n\n      config = {\n        ...config,\n        outputFormat: options.format as OutputFormat,\n        ocrEnabled: options.ocr !== false,\n        ocrServerUrl: options.ocrServerUrl,\n        ocrLanguage: options.ocrLanguage,\n        numWorkers: parseInt(options.numWorkers || calculatedNumWorkers.toString()),\n        maxPages: parseInt(options.maxPages || DEFAULT_MAX_PAGES.toString()),\n        targetPages: options.targetPages,\n        dpi: parseInt(options.dpi || DEFAULT_DPI.toString()),\n        preciseBoundingBox: options.preciseBbox !== false,\n        preserveVerySmallText: options.preserveSmallText || false,\n        password: options.password,\n      };\n\n      // Build debug config if any debug flags are set\n      if (options.debug || options.debugVisualize) {\n        let regionFilter: { x1: number; y1: number; x2: number; y2: number } | undefined;\n        if (options.debugRegion) {\n          const [x1, y1, x2, y2] = options.debugRegion.split(\",\").map(Number);\n          regionFilter = { x1, y1, x2, y2 };\n        }\n        config.debug = {\n          enabled: true,\n          visualize: options.debugVisualize,\n          visualizePath: options.debugOutput ?? \"./debug-output\",\n          outputPath: options.debugOutput ? `${options.debugOutput}/debug.log` : undefined,\n          textFilter: options.debugTextFilter,\n          pageFilter: options.debugPage ? parseInt(options.debugPage) : undefined,\n          regionFilter,\n        };\n      }\n\n      // Create parser\n      const parser = new LiteParse(config);\n\n      // Read from stdin or file\n      let input: string | Buffer;\n      if (isStdin) {\n        const chunks: Buffer[] = [];\n        for await (const chunk of process.stdin) {\n          chunks.push(chunk);\n        }\n        input = Buffer.concat(chunks);\n        if (input.length === 0) {\n          console.error(\"Error: No data received from stdin\");\n          process.exit(1);\n        }\n      } else {\n        input = file;\n      }\n\n      // Parse document (quiet flag controls progress output)\n      const result = await parser.parse(input, quiet);\n\n      // Format output based on format\n      let output: string;\n      switch (config.outputFormat) {\n        case \"json\":\n          output = JSON.stringify(result.json, null, 2);\n          break;\n        case \"text\":\n        default:\n          output = result.text;\n          break;\n      }\n\n      // Write to file or stdout\n      if (options.output) {\n        await fs.writeFile(options.output, output);\n        if (!quiet) {\n          console.error(`\\n✓ Parsed ${result.pages.length} pages → ${options.output}`);\n        }\n      } else {\n        // Output result to stdout (can be piped)\n        console.log(output);\n      }\n    } catch (error: unknown) {\n      const message = error instanceof Error ? error.message : String(error);\n      const stack = error instanceof Error ? error.stack : undefined;\n      console.error(`\\nError: ${message}`);\n      if (stack) {\n        console.error(stack);\n      }\n      process.exit(1);\n    }\n  });\n\nprogram\n  .command(\"screenshot <file>\")\n  .description(\"Generate screenshots of PDF pages\")\n  .option(\"-o, --output-dir <dir>\", \"Output directory for screenshots\", DEFAULT_SCREENSHOT_DIR)\n  .option(\"--target-pages <pages>\", 'Page numbers to screenshot (e.g., \"1,3,5\" or \"1-5\")')\n  .option(\"--dpi <dpi>\", \"DPI for rendering\", DEFAULT_DPI.toString())\n  .option(\"--format <format>\", \"Image format: png|jpg\", DEFAULT_SCREENSHOT_FORMAT)\n  .option(\"--password <password>\", \"Password for encrypted/protected documents\")\n  .option(\"--config <file>\", \"Config file (JSON)\")\n  .option(\"-q, --quiet\", \"Suppress progress output\")\n  .action(async (file: string, options: ScreenshotCommandOptions) => {\n    try {\n      const quiet = options.quiet || false;\n\n      // Check if file exists\n      if (!existsSync(file)) {\n        console.error(`Error: File not found: ${file}`);\n        process.exit(1);\n      }\n\n      let config: Partial<LiteParseConfig> = {};\n\n      // Load config file if provided\n      if (options.config) {\n        if (!existsSync(options.config)) {\n          console.error(`Error: Config file not found: ${options.config}`);\n          process.exit(1);\n        }\n        const configData = await fs.readFile(options.config, \"utf-8\");\n        config = JSON.parse(configData);\n      }\n\n      // Override with CLI options\n      config = {\n        ...config,\n        dpi: parseInt(options.dpi || DEFAULT_DPI.toString()),\n        password: options.password,\n      };\n\n      // Parse target pages\n      let pageNumbers: number[] | undefined;\n      if (options.targetPages) {\n        pageNumbers = parsePageNumbers(options.targetPages);\n      }\n\n      const outputDir = options.outputDir || DEFAULT_SCREENSHOT_DIR;\n\n      // Create output directory\n      if (!existsSync(outputDir)) {\n        await fs.mkdir(outputDir, { recursive: true });\n      }\n\n      // Create parser\n      const parser = new LiteParse(config);\n\n      // Generate screenshots\n      const results = await parser.screenshot(file, pageNumbers, quiet);\n\n      // Save screenshots\n      for (const result of results) {\n        const filename = `page_${result.pageNum}.${options.format || DEFAULT_SCREENSHOT_FORMAT}`;\n        const filepath = path.join(outputDir, filename);\n        await fs.writeFile(filepath, result.imageBuffer);\n        if (!quiet) {\n          console.error(`✓ ${filepath} (${result.width}x${result.height})`);\n        }\n      }\n\n      if (!quiet) {\n        console.error(`\\n✓ Generated ${results.length} screenshots → ${outputDir}`);\n      }\n    } catch (error: unknown) {\n      const message = error instanceof Error ? error.message : String(error);\n      const stack = error instanceof Error ? error.stack : undefined;\n      console.error(`\\nError: ${message}`);\n      if (stack) {\n        console.error(stack);\n      }\n      process.exit(1);\n    }\n  });\n\n// Supported file extensions for batch parsing\nconst SUPPORTED_EXTENSIONS = new Set([\n  \".pdf\",\n  \".doc\",\n  \".docx\",\n  \".docm\",\n  \".dot\",\n  \".dotm\",\n  \".dotx\",\n  \".odt\",\n  \".ott\",\n  \".ppt\",\n  \".pptx\",\n  \".pptm\",\n  \".pot\",\n  \".potm\",\n  \".potx\",\n  \".odp\",\n  \".otp\",\n  \".xls\",\n  \".xlsx\",\n  \".xlsm\",\n  \".xlsb\",\n  \".ods\",\n  \".ots\",\n  \".csv\",\n  \".tsv\",\n  \".jpg\",\n  \".jpeg\",\n  \".png\",\n  \".gif\",\n  \".bmp\",\n  \".tiff\",\n  \".tif\",\n  \".webp\",\n  \".svg\",\n  \".rtf\",\n  \".pages\",\n  \".key\",\n  \".numbers\",\n]);\n\nprogram\n  .command(\"batch-parse <input-dir> <output-dir>\")\n  .description(\"Parse multiple documents in batch mode\")\n  .option(\"--format <format>\", \"Output format: json|text\", DEFAULT_OUTPUT_FORMAT)\n  .option(\"--ocr-server-url <url>\", \"HTTP OCR server URL (uses Tesseract if not provided)\")\n  .option(\"--no-ocr\", \"Disable OCR\")\n  .option(\"--ocr-language <lang>\", \"OCR language(s)\", DEFAULT_LANGUAGE)\n  .option(\n    \"--num-workers <n>\",\n    \"Number of pages to OCR in parallel. Defaults to number of CPU cores minus one.\"\n  )\n  .option(\"--max-pages <n>\", \"Max pages to parse per file\", DEFAULT_MAX_PAGES.toString())\n  .option(\"--dpi <dpi>\", \"DPI for rendering\", DEFAULT_DPI.toString())\n  .option(\"--no-precise-bbox\", \"Disable precise bounding boxes\")\n  .option(\"--recursive\", \"Recursively search input directory\")\n  .option(\"--extension <ext>\", 'Only process files with this extension (e.g., \".pdf\")')\n  .option(\n    \"--password <password>\",\n    \"Password for encrypted/protected documents (applied to all files)\"\n  )\n  .option(\"--config <file>\", \"Config file (JSON)\")\n  .option(\"-q, --quiet\", \"Suppress progress output\")\n  .action(async (inputDir: string, outputDir: string, options: BatchParseCommandOptions) => {\n    try {\n      const quiet = options.quiet || false;\n      const startTime = performance.now();\n\n      // Validate input directory\n      if (!existsSync(inputDir)) {\n        console.error(`Error: Input directory not found: ${inputDir}`);\n        process.exit(1);\n      }\n\n      const inputStat = statSync(inputDir);\n      if (!inputStat.isDirectory()) {\n        console.error(`Error: Input path is not a directory: ${inputDir}`);\n        process.exit(1);\n      }\n\n      // Create output directory\n      if (!existsSync(outputDir)) {\n        await fs.mkdir(outputDir, { recursive: true });\n      }\n\n      // Find all files to process\n      const files = findFiles(inputDir, options.recursive || false, options.extension);\n\n      if (files.length === 0) {\n        console.error(\"No supported files found in input directory\");\n        process.exit(1);\n      }\n\n      if (!quiet) {\n        console.error(`Found ${files.length} files to process`);\n      }\n\n      // Load config\n      let config: Partial<LiteParseConfig> = {};\n      if (options.config) {\n        if (!existsSync(options.config)) {\n          console.error(`Error: Config file not found: ${options.config}`);\n          process.exit(1);\n        }\n        const configData = await fs.readFile(options.config, \"utf-8\");\n        config = JSON.parse(configData);\n      }\n\n      // Apply CLI options\n      let calculatedNumWorkers = os.cpus().length - 1;\n      if (calculatedNumWorkers < 1) {\n        calculatedNumWorkers = 1;\n      }\n\n      config = {\n        ...config,\n        outputFormat: options.format as OutputFormat,\n        ocrEnabled: options.ocr !== false,\n        ocrServerUrl: options.ocrServerUrl,\n        ocrLanguage: options.ocrLanguage,\n        numWorkers: parseInt(options.numWorkers || calculatedNumWorkers.toString()),\n        maxPages: parseInt(options.maxPages || DEFAULT_MAX_PAGES.toString()),\n        dpi: parseInt(options.dpi || DEFAULT_DPI.toString()),\n        preciseBoundingBox: options.preciseBbox !== false,\n        password: options.password,\n      };\n\n      // Create a SINGLE parser instance for all files (key for batch efficiency)\n      const parser = new LiteParse(config);\n\n      // Process files\n      let successCount = 0;\n      let errorCount = 0;\n      const outputExt = options.format === \"json\" ? \".json\" : \".txt\";\n\n      for (let i = 0; i < files.length; i++) {\n        const file = files[i];\n        const relativePath = path.relative(inputDir, file);\n        const outputPath = path.join(outputDir, relativePath.replace(/\\.[^.]+$/, outputExt));\n\n        // Create output subdirectory if needed\n        const outputSubdir = path.dirname(outputPath);\n        if (!existsSync(outputSubdir)) {\n          await fs.mkdir(outputSubdir, { recursive: true });\n        }\n\n        try {\n          const fileStart = performance.now();\n          const result = await parser.parse(file, true); // Always quiet for individual files\n\n          // Format output\n          let output: string;\n          if (options.format === \"json\") {\n            output = JSON.stringify(result.json, null, 2);\n          } else {\n            output = result.text;\n          }\n\n          await fs.writeFile(outputPath, output);\n          successCount++;\n\n          if (!quiet) {\n            const fileTime = (performance.now() - fileStart).toFixed(0);\n            console.error(\n              `[${i + 1}/${files.length}] ✓ ${relativePath} (${result.pages.length} pages, ${fileTime}ms)`\n            );\n          }\n        } catch (error: unknown) {\n          errorCount++;\n          if (!quiet) {\n            const message = error instanceof Error ? error.message : String(error);\n            console.error(`[${i + 1}/${files.length}] ✗ ${relativePath}: ${message}`);\n          }\n        }\n      }\n\n      const totalTime = ((performance.now() - startTime) / 1000).toFixed(2);\n      const avgTime =\n        files.length > 0 ? ((performance.now() - startTime) / files.length).toFixed(0) : 0;\n\n      if (!quiet) {\n        console.error(\"\");\n        console.error(`Batch complete: ${successCount} succeeded, ${errorCount} failed`);\n        console.error(`Total time: ${totalTime}s (avg ${avgTime}ms/file)`);\n        console.error(`Output: ${outputDir}`);\n      }\n\n      if (errorCount > 0) {\n        process.exit(1);\n      }\n    } catch (error: unknown) {\n      const message = error instanceof Error ? error.message : String(error);\n      const stack = error instanceof Error ? error.stack : undefined;\n      console.error(`\\nError: ${message}`);\n      if (stack) {\n        console.error(stack);\n      }\n      process.exit(1);\n    }\n  });\n\n/**\n * Find all supported files in a directory\n */\nfunction findFiles(dir: string, recursive: boolean, filterExt?: string): string[] {\n  const files: string[] = [];\n\n  function scan(currentDir: string) {\n    const entries = readdirSync(currentDir);\n\n    for (const entry of entries) {\n      const fullPath = path.join(currentDir, entry);\n      const stat = statSync(fullPath);\n\n      if (stat.isDirectory()) {\n        if (recursive) {\n          scan(fullPath);\n        }\n      } else if (stat.isFile()) {\n        const ext = path.extname(entry).toLowerCase();\n\n        // Filter by extension if specified\n        if (filterExt && ext !== filterExt.toLowerCase()) {\n          continue;\n        }\n\n        // Check if supported\n        if (SUPPORTED_EXTENSIONS.has(ext)) {\n          files.push(fullPath);\n        }\n      }\n    }\n  }\n\n  scan(dir);\n  return files.sort();\n}\n\n/**\n * Parse page numbers from string like \"1,3,5\" or \"1-5,10\"\n */\nfunction parsePageNumbers(pagesStr: string): number[] {\n  const pages: number[] = [];\n  const parts = pagesStr.split(\",\");\n\n  for (const part of parts) {\n    const trimmed = part.trim();\n    if (trimmed.includes(\"-\")) {\n      const [start, end] = trimmed.split(\"-\").map((n) => parseInt(n.trim()));\n      for (let i = start; i <= end; i++) {\n        pages.push(i);\n      }\n    } else {\n      pages.push(parseInt(trimmed));\n    }\n  }\n\n  return [...new Set(pages)].sort((a, b) => a - b);\n}\n\nexport { program };\n"
  },
  {
    "path": "dataset_eval_utils/README.md",
    "content": "# LiteParse Eval Utils\n\nUtilities for generating and evaluating datasets for PDF parsing performance. Compares text extraction quality across multiple PDF parsers using LLM-based QA evaluation.\n\n## Setup\n\nRequires Python 3.12+.\n\n```bash\n# Install the package (from the dataset_eval_utils directory)\npip install -e .\n```\n\nYou'll need an `ANTHROPIC_API_KEY` environment variable set for the LLM-based evaluation and dataset processing tools.\n\n## Dataset\n\nAn existing dataset that was generated and evaluated using this framework can be found on [huggingface]().\n\nYou can download the dataset using the Hugging Face CLI:\n\n```bash\nhf download run-llama/liteparse-eval-dataset --repo-type dataset --local-dir ./liteparse-eval-dataset\n```\n\n## CLI Tools\n\n### `lp-process` — Generate Ground Truth Datasets\n\nProcesses PDF and image files using Claude's vision capabilities to generate structured QA ground truth data.\n\n```bash\nlp-process /path/to/documents --output-dir ./ground_truth\n```\n\nOptions:\n- `--output-dir` — Directory to save output JSON files (default: `./output`)\n- `--model` — Claude model to use (default: `claude-sonnet-4-5-20250929`)\n- `--api-key` — Anthropic API key (or set `ANTHROPIC_API_KEY` env var)\n\nEach output JSON file contains document metadata and QA pairs extracted from the document pages.\n\n### `lp-evaluate` — Run QA Evaluation\n\nEvaluates parser text extraction quality by having an LLM answer questions from extracted text and judging correctness against ground truth answers.\n\n```bash\nlp-evaluate \\\n  --data-dir ./documents \\\n  --ground-truth-dir ./ground_truth \\\n  --parse-provider liteparse \\\n  --output ./results/run1\n```\n\nOptions:\n- `--data-dir` — Directory containing source PDF documents (required)\n- `--ground-truth-dir` — Directory containing ground truth JSON files (required)\n- `--output` — Path to save results (JSON + HTML report)\n- `--parse-provider` — Parser to evaluate: `liteparse`, `pymupdf`, `pypdf`, `markitdown` (default: `liteparse`)\n- `--llm-provider` — LLM for answering questions: `anthropic` (default: `anthropic`)\n\nOutputs:\n- `<output>.json` — Aggregate results with pass rates\n- `<output>_detailed.json` — Per-document results with extracted text and individual QA results\n- `<output>_report.html` — Interactive HTML report with PDF previews and QA breakdowns\n\n### `lp-benchmark` — Performance Benchmarking\n\nMeasures parse latency and memory usage across providers.\n\n```bash\nlp-benchmark document.pdf --providers pymupdf liteparse --runs 20\n```\n\nOptions:\n- `--providers` — Providers to benchmark (default: all local providers)\n- `--runs` — Number of benchmark runs per provider (default: 10)\n- `--warmup` — Number of warmup runs (default: 1)\n- `--output` — Path to save JSON results\n\n## Parser Providers\n\n| Provider | Library | Notes |\n|----------|---------|-------|\n| `liteparse` | [liteparse](https://github.com/run-llama/liteparse) | Spatial text extraction with OCR support |\n| `pymupdf` | [PyMuPDF](https://pymupdf.readthedocs.io/) | Fast, mature PDF library |\n| `pypdf` | [pypdf](https://pypdf.readthedocs.io/) | Pure-Python PDF library |\n| `markitdown` | [MarkItDown](https://github.com/microsoft/markitdown) | Microsoft's document-to-markdown converter |\n\n## Evaluation Pipeline\n\n1. **Extract text** from PDF using the selected parser provider\n2. **Answer questions** — LLM reads the extracted text and answers ground truth questions\n3. **Judge answers** — A separate LLM judge evaluates whether predicted answers are semantically equivalent to expected answers\n4. **Aggregate** — Pass rates are computed per-document and overall\n"
  },
  {
    "path": "dataset_eval_utils/pyproject.toml",
    "content": "[project]\nname = \"liteparse-eval\"\nversion = \"0.1.0\"\ndescription = \"Utilities for generating and evaluating datasets for PDF parsing performance.\"\nreadme = \"README.md\"\nrequires-python = \">=3.12\"\ndependencies = [\n    \"anthropic>=0.76.0\",\n    \"pillow>=10.0.0\",\n    \"pymupdf>=1.26.7\",\n    \"pypdf>=6.6.2\",\n    \"markitdown[all]\",\n    \"rapidfuzz>=3.14.3\",\n    \"liteparse @ file:///${PROJECT_ROOT}/../packages/python\",\n]\n\n[project.scripts]\nlp-evaluate = \"liteparse_eval.evaluation:main\"\nlp-process = \"liteparse_eval.processing:main\"\nlp-benchmark = \"liteparse_eval.benchmark:main\"\n\n[tool.setuptools]\npackage-dir = {\"\" = \"src\"}\n\n[tool.setuptools.packages.find]\nwhere = [\"src\"]\n"
  },
  {
    "path": "dataset_eval_utils/src/liteparse_eval/__init__.py",
    "content": "\"\"\"LiteParse Eval - Document parsing evaluation and benchmarking toolkit.\"\"\"\n\nfrom liteparse_eval.providers import (\n    LLMProvider,\n    AnthropicProvider,\n    ParserProvider,\n    LiteparseProvider,\n    MarkItDownProvider,\n    PyMuPDFProvider,\n    PyPDFProvider,\n)\n\n__version__ = \"0.1.0\"\n__all__ = [\n    \"LLMProvider\",\n    \"AnthropicProvider\",\n    \"ParserProvider\",\n    \"LiteparseProvider\",\n    \"MarkItDownProvider\",\n    \"PyMuPDFProvider\",\n    \"PyPDFProvider\",\n]\n"
  },
  {
    "path": "dataset_eval_utils/src/liteparse_eval/benchmark.py",
    "content": "\"\"\"\nPerformance benchmarking tool for parser providers.\n\nMeasures latency and resource usage across multiple runs for a given document.\n\"\"\"\n\nimport argparse\nimport gc\nimport json\nimport statistics\nimport time\nimport tracemalloc\nfrom dataclasses import dataclass, field\nfrom pathlib import Path\nfrom typing import Optional\n\nfrom liteparse_eval.providers import (\n    ParserProvider,\n    LiteparseProvider,\n    MarkItDownProvider,\n    PyMuPDFProvider,\n    PyPDFProvider,\n)\n\n\n@dataclass\nclass BenchmarkMetrics:\n    \"\"\"Performance metrics for a benchmark run.\"\"\"\n    latencies: list[float] = field(default_factory=list)  # seconds\n    memory_peaks: list[float] = field(default_factory=list)  # MB\n\n    @property\n    def count(self) -> int:\n        return len(self.latencies)\n\n    @property\n    def latency_avg(self) -> float:\n        return statistics.mean(self.latencies) if self.latencies else 0.0\n\n    @property\n    def latency_median(self) -> float:\n        return statistics.median(self.latencies) if self.latencies else 0.0\n\n    @property\n    def latency_stddev(self) -> float:\n        return statistics.stdev(self.latencies) if len(self.latencies) >= 2 else 0.0\n\n    @property\n    def latency_min(self) -> float:\n        return min(self.latencies) if self.latencies else 0.0\n\n    @property\n    def latency_max(self) -> float:\n        return max(self.latencies) if self.latencies else 0.0\n\n    @property\n    def memory_avg(self) -> float:\n        return statistics.mean(self.memory_peaks) if self.memory_peaks else 0.0\n\n    @property\n    def memory_median(self) -> float:\n        return statistics.median(self.memory_peaks) if self.memory_peaks else 0.0\n\n    @property\n    def memory_stddev(self) -> float:\n        return statistics.stdev(self.memory_peaks) if len(self.memory_peaks) >= 2 else 0.0\n\n    @property\n    def memory_min(self) -> float:\n        return min(self.memory_peaks) if self.memory_peaks else 0.0\n\n    @property\n    def memory_max(self) -> float:\n        return max(self.memory_peaks) if self.memory_peaks else 0.0\n\n    def to_dict(self) -> dict:\n        \"\"\"Convert to dictionary for JSON serialization.\"\"\"\n        return {\n            \"runs\": self.count,\n            \"latency\": {\n                \"avg_seconds\": round(self.latency_avg, 4),\n                \"median_seconds\": round(self.latency_median, 4),\n                \"stddev_seconds\": round(self.latency_stddev, 4),\n                \"min_seconds\": round(self.latency_min, 4),\n                \"max_seconds\": round(self.latency_max, 4),\n                \"all_runs\": [round(l, 4) for l in self.latencies],\n            },\n            \"memory\": {\n                \"avg_mb\": round(self.memory_avg, 2),\n                \"median_mb\": round(self.memory_median, 2),\n                \"stddev_mb\": round(self.memory_stddev, 2),\n                \"min_mb\": round(self.memory_min, 2),\n                \"max_mb\": round(self.memory_max, 2),\n                \"all_runs\": [round(m, 2) for m in self.memory_peaks],\n            },\n        }\n\n\n@dataclass\nclass ProviderBenchmarkResult:\n    \"\"\"Result for a single provider benchmark.\"\"\"\n    provider_name: str\n    metrics: BenchmarkMetrics\n    success: bool = True\n    error: Optional[str] = None\n    extracted_text_length: Optional[int] = None\n\n    def to_dict(self) -> dict:\n        result = {\n            \"provider\": self.provider_name,\n            \"success\": self.success,\n            \"metrics\": self.metrics.to_dict() if self.success else None,\n        }\n        if self.error:\n            result[\"error\"] = self.error\n        if self.extracted_text_length is not None:\n            result[\"extracted_text_length\"] = self.extracted_text_length\n        return result\n\n\ndef get_provider_instance(provider_name: str) -> ParserProvider:\n    \"\"\"Create a fresh provider instance by name.\"\"\"\n    providers = {\n        \"pymupdf\": PyMuPDFProvider,\n        \"pypdf\": PyPDFProvider,\n        \"markitdown\": MarkItDownProvider,\n        \"liteparse\": LiteparseProvider,\n    }\n    if provider_name not in providers:\n        raise ValueError(f\"Unknown provider: {provider_name}\")\n    return providers[provider_name]()\n\n\ndef benchmark_provider(\n    provider: ParserProvider,\n    file_path: Path,\n    num_runs: int = 10,\n    warmup_runs: int = 1,\n) -> BenchmarkMetrics:\n    \"\"\"\n    Benchmark a parser provider on a document.\n\n    Args:\n        provider: The parser provider to benchmark\n        file_path: Path to the document to parse\n        num_runs: Number of benchmark runs (default: 10)\n        warmup_runs: Number of warmup runs before benchmarking (default: 1)\n\n    Returns:\n        BenchmarkMetrics with latency and memory measurements\n    \"\"\"\n    metrics = BenchmarkMetrics()\n\n    # Warmup runs (not recorded)\n    for _ in range(warmup_runs):\n        provider.extract_text(file_path)\n        gc.collect()\n\n    # Benchmark runs\n    for _ in range(num_runs):\n        gc.collect()\n\n        # Start memory tracking\n        tracemalloc.start()\n\n        # Time the extraction\n        start_time = time.perf_counter()\n        provider.extract_text(file_path)\n        elapsed = time.perf_counter() - start_time\n\n        # Get peak memory\n        _, peak_memory = tracemalloc.get_traced_memory()\n        tracemalloc.stop()\n\n        metrics.latencies.append(elapsed)\n        metrics.memory_peaks.append(peak_memory / (1024 * 1024))  # Convert to MB\n\n        gc.collect()\n\n    return metrics\n\n\ndef run_benchmark(\n    file_path: Path,\n    providers: list[str],\n    num_runs: int = 10,\n    warmup_runs: int = 1,\n    output_path: Optional[Path] = None,\n) -> dict:\n    \"\"\"\n    Run benchmark across multiple providers.\n\n    Args:\n        file_path: Path to the document to benchmark\n        providers: List of provider names to benchmark\n        num_runs: Number of runs per provider\n        warmup_runs: Number of warmup runs per provider\n        output_path: Optional path to save JSON results\n\n    Returns:\n        Dictionary with benchmark results for all providers\n    \"\"\"\n    results: list[ProviderBenchmarkResult] = []\n\n    print(f\"Benchmarking: {file_path}\")\n    print(f\"Runs per provider: {num_runs} (+ {warmup_runs} warmup)\")\n    print(\"=\" * 60)\n\n    for provider_name in providers:\n        print(f\"\\n{provider_name}:\")\n        print(\"-\" * 40)\n\n        try:\n            provider = get_provider_instance(provider_name)\n\n            # Get text length from first extraction\n            text = provider.extract_text(file_path)\n            text_length = len(text)\n\n            metrics = benchmark_provider(\n                provider=provider,\n                file_path=file_path,\n                num_runs=num_runs,\n                warmup_runs=warmup_runs,\n            )\n\n            result = ProviderBenchmarkResult(\n                provider_name=provider_name,\n                metrics=metrics,\n                extracted_text_length=text_length,\n            )\n\n            print(f\"  Latency:  avg={metrics.latency_avg:.3f}s  median={metrics.latency_median:.3f}s  stddev={metrics.latency_stddev:.3f}s\")\n            print(f\"  Memory:   avg={metrics.memory_avg:.1f}MB  median={metrics.memory_median:.1f}MB  stddev={metrics.memory_stddev:.1f}MB\")\n            print(f\"  Text length: {text_length:,} chars\")\n\n        except Exception as e:\n            result = ProviderBenchmarkResult(\n                provider_name=provider_name,\n                metrics=BenchmarkMetrics(),\n                success=False,\n                error=str(e),\n            )\n            print(f\"  ERROR: {e}\")\n\n        results.append(result)\n\n    # Build output\n    output = {\n        \"file\": str(file_path),\n        \"num_runs\": num_runs,\n        \"warmup_runs\": warmup_runs,\n        \"providers\": [r.to_dict() for r in results],\n    }\n\n    # Print summary\n    print(\"\\n\" + \"=\" * 60)\n    print(\"SUMMARY\")\n    print(\"=\" * 60)\n    print(f\"{'Provider':<15} {'Avg Latency':<12} {'Median':<12} {'Avg Memory':<12}\")\n    print(\"-\" * 60)\n    for r in results:\n        if r.success:\n            print(f\"{r.provider_name:<15} {r.metrics.latency_avg:<12.3f} {r.metrics.latency_median:<12.3f} {r.metrics.memory_avg:<12.1f}\")\n        else:\n            print(f\"{r.provider_name:<15} {'FAILED':<12} {'':<12} {'':<12}\")\n\n    # Save results\n    if output_path:\n        with open(output_path, \"w\") as f:\n            json.dump(output, f, indent=2)\n        print(f\"\\nResults saved to: {output_path}\")\n\n    return output\n\n\ndef main():\n    \"\"\"CLI entry point for the benchmark tool.\"\"\"\n    parser = argparse.ArgumentParser(\n        description=\"Benchmark parse providers on a document for latency and resource usage\"\n    )\n    parser.add_argument(\n        \"file\",\n        type=Path,\n        help=\"Path to the document to benchmark\"\n    )\n    parser.add_argument(\n        \"--providers\",\n        type=str,\n        nargs=\"+\",\n        choices=[\"pymupdf\", \"pypdf\", \"markitdown\", \"liteparse\"],\n        default=[\"pymupdf\", \"pypdf\", \"markitdown\", \"liteparse\"],\n        help=\"Parse providers to benchmark (default: all local providers)\"\n    )\n    parser.add_argument(\n        \"--runs\",\n        type=int,\n        default=10,\n        help=\"Number of benchmark runs per provider (default: 10)\"\n    )\n    parser.add_argument(\n        \"--warmup\",\n        type=int,\n        default=1,\n        help=\"Number of warmup runs before benchmarking (default: 1)\"\n    )\n    parser.add_argument(\n        \"--output\",\n        type=Path,\n        help=\"Path to save JSON results\"\n    )\n\n    args = parser.parse_args()\n\n    if not args.file.exists():\n        print(f\"Error: File not found: {args.file}\")\n        return 1\n\n    run_benchmark(\n        file_path=args.file,\n        providers=args.providers,\n        num_runs=args.runs,\n        warmup_runs=args.warmup,\n        output_path=args.output,\n    )\n\n    return 0\n\n\nif __name__ == \"__main__\":\n    exit(main())\n"
  },
  {
    "path": "dataset_eval_utils/src/liteparse_eval/evaluation.py",
    "content": "\"\"\"\nEvaluation and benchmarking script for text extraction and LLM-based document understanding.\n\nThis script provides:\n1. LLM QA evaluation using an LLM judge for pass/fail evaluation\n2. Latency tracking for LLM and parse operations\n\"\"\"\n\nimport argparse\nimport json\nimport time\nfrom dataclasses import dataclass, field\nfrom pathlib import Path\nfrom typing import List, Optional\n\nfrom liteparse_eval.providers import (\n    ParserProvider,\n    LLMProvider,\n    AnthropicProvider,\n    LiteparseProvider,\n    MarkItDownProvider,\n    PyMuPDFProvider,\n    PyPDFProvider,\n)\n\n\n@dataclass\nclass LatencyMetrics:\n    \"\"\"Latency metrics for provider calls.\"\"\"\n    latencies: List[float] = field(default_factory=list)  # Individual call latencies in seconds\n\n    @property\n    def count(self) -> int:\n        \"\"\"Number of calls.\"\"\"\n        return len(self.latencies)\n\n    @property\n    def average(self) -> float:\n        \"\"\"Average latency in seconds.\"\"\"\n        return sum(self.latencies) / len(self.latencies) if self.latencies else 0.0\n\n    @property\n    def min(self) -> float:\n        \"\"\"Minimum latency in seconds.\"\"\"\n        return min(self.latencies) if self.latencies else 0.0\n\n    @property\n    def max(self) -> float:\n        \"\"\"Maximum latency in seconds.\"\"\"\n        return max(self.latencies) if self.latencies else 0.0\n\n    @property\n    def stddev(self) -> float:\n        \"\"\"Standard deviation of latency in seconds.\"\"\"\n        if not self.latencies or len(self.latencies) < 2:\n            return 0.0\n        mean = self.average\n        variance = sum((x - mean) ** 2 for x in self.latencies) / len(self.latencies)\n        return variance ** 0.5\n\n    @property\n    def total(self) -> float:\n        \"\"\"Total latency in seconds.\"\"\"\n        return sum(self.latencies) if self.latencies else 0.0\n\n    def to_dict(self) -> dict:\n        \"\"\"Convert to dictionary for JSON serialization.\"\"\"\n        return {\n            \"count\": self.count,\n            \"total_seconds\": round(self.total, 3),\n            \"average_seconds\": round(self.average, 3),\n            \"min_seconds\": round(self.min, 3),\n            \"max_seconds\": round(self.max, 3),\n            \"stddev_seconds\": round(self.stddev, 3),\n            \"individual_latencies\": [round(lat, 3) for lat in self.latencies]\n        }\n\n\n@dataclass\nclass QAResult:\n    \"\"\"Result for a single QA pair evaluation.\"\"\"\n    question: str\n    expected_answer: str\n    predicted_answer: str\n    llm_judge_pass: bool\n\n\n@dataclass\nclass QAEvalResult:\n    \"\"\"Results for QA evaluation on a single document.\"\"\"\n    file_path: Path\n    total_questions: int\n    llm_judge_pass_rate: float\n    qa_results: List[QAResult]\n    llm_latency_metrics: Optional[LatencyMetrics] = None\n    parse_latency_seconds: Optional[float] = None\n\n\nclass Benchmark:\n    \"\"\"Main benchmark runner for text extraction and QA evaluation.\"\"\"\n\n    def __init__(\n        self,\n        parser_provider: Optional[ParserProvider] = None,\n        llm_provider: Optional[LLMProvider] = None,\n        llm_judge_provider: Optional[LLMProvider] = None,\n    ):\n        \"\"\"\n        Initialize the benchmark.\n\n        Args:\n            parser_provider: Parser provider to use for text extraction\n            llm_provider: LLM provider to use for answering questions\n            llm_judge_provider: LLM provider for judge-based evaluation\n        \"\"\"\n        self.parser_provider = parser_provider\n        self.llm_provider = llm_provider\n        self.llm_judge_provider = llm_judge_provider\n\n    def run_qa_eval(\n        self,\n        extracted_text: str,\n        doc_path: Path,\n        ground_truth_path: Path,\n        parse_latency: Optional[float] = None\n    ) -> QAEvalResult:\n        \"\"\"\n        Run QA evaluation on a single document.\n\n        Args:\n            extracted_text: Extracted text from the document\n            doc_path: Path to the source document\n            ground_truth_path: Path to the ground truth JSON file\n            parse_latency: Time taken for text extraction in seconds\n\n        Returns:\n            QAEvalResult with evaluation metrics\n        \"\"\"\n        if not self.llm_provider or not self.llm_judge_provider:\n            raise ValueError(\"LLM provider and judge provider must be configured\")\n\n        # Load ground truth\n        with open(ground_truth_path, \"r\") as f:\n            ground_truth = json.load(f)\n\n        # Get predicted answers with latency tracking\n        predicted_answers = []\n        llm_latency_metrics = LatencyMetrics()\n        for qa_pair in ground_truth[\"qa_pairs\"]:\n            start_time = time.perf_counter()\n            answer = self.llm_provider.answer_question(extracted_text, qa_pair[\"question\"])\n            latency = time.perf_counter() - start_time\n            llm_latency_metrics.latencies.append(latency)\n            predicted_answers.append(answer)\n\n        # Evaluate with LLM judge\n        qa_results = []\n        judge_passes = 0\n\n        for predicted, gt_pair in zip(predicted_answers, ground_truth[\"qa_pairs\"]):\n            question = gt_pair[\"question\"]\n            expected = gt_pair[\"answer\"]\n\n            try:\n                llm_judge_pass = self.llm_judge_provider.evaluate_answer(question, expected, predicted)\n            except Exception as e:\n                print(f\"  Warning: LLM judge evaluation failed: {e}\")\n                llm_judge_pass = False\n\n            if llm_judge_pass:\n                judge_passes += 1\n\n            qa_results.append(QAResult(\n                question=question,\n                expected_answer=expected,\n                predicted_answer=predicted,\n                llm_judge_pass=llm_judge_pass,\n            ))\n\n        total = len(ground_truth[\"qa_pairs\"])\n        llm_judge_pass_rate = judge_passes / total if total > 0 else 0.0\n\n        result = QAEvalResult(\n            file_path=doc_path,\n            total_questions=total,\n            llm_judge_pass_rate=llm_judge_pass_rate,\n            qa_results=qa_results,\n            llm_latency_metrics=llm_latency_metrics,\n            parse_latency_seconds=parse_latency,\n        )\n        return result\n\n    def run_full_benchmark(\n        self,\n        data_dir: Path,\n        ground_truth_dir: Path,\n        output_path: Optional[Path] = None\n    ) -> dict:\n        \"\"\"\n        Run full benchmark across all documents using batch extraction.\n\n        Args:\n            data_dir: Directory containing input documents\n            ground_truth_dir: Directory containing ground truth JSON files\n            output_path: Optional path to save detailed results\n\n        Returns:\n            Dictionary with aggregated benchmark results\n        \"\"\"\n        qa_results: list[QAEvalResult] = []\n        extracted_texts: dict[str, str] = {}  # Store extracted text for each document\n\n        # Find all ground truth files\n        gt_files = sorted(ground_truth_dir.glob(\"*.json\"))\n\n        print(f\"Running benchmark on {len(gt_files)} documents...\")\n\n        # Find all source documents and match them to ground truth files\n        source_docs = sorted(data_dir.glob(\"*.pdf\"))\n        doc_gt_pairs: list[tuple[Path, Path]] = []\n\n        for gt_path in gt_files:\n            source_doc = next((\n                doc for doc in source_docs if doc.stem == gt_path.stem\n            ), None)\n\n            if not source_doc:\n                print(f\"  Warning: Could not find source document for {gt_path.name}\")\n                continue\n\n            doc_gt_pairs.append((source_doc, gt_path))\n\n        if not doc_gt_pairs:\n            print(\"No documents found to process.\")\n            return {}\n\n        # Extract text\n        parse_latency_per_doc: dict[Path, float] = {}\n        if self.parser_provider:\n            docs_to_extract = [doc for doc, _ in doc_gt_pairs]\n\n            for doc_path in docs_to_extract:\n                start_time = time.perf_counter()\n                try:\n                    parse_result = self.parser_provider.extract_text(doc_path)\n                    total_time = time.perf_counter() - start_time\n\n                    extracted_texts[str(doc_path)] = parse_result\n                    parse_latency_per_doc[doc_path] = total_time\n                except Exception as e:\n                    print(f\"  Error: extraction failed: {e}\")\n                    parse_result = \"\"\n\n        # Run QA evaluation for each document\n        for i, (source_doc, gt_path) in enumerate(doc_gt_pairs, 1):\n            print(f\"\\n[{i}/{len(doc_gt_pairs)}] Evaluating: {gt_path.name}\")\n\n            extracted_text = extracted_texts.get(str(source_doc), \"\")\n            parse_latency = parse_latency_per_doc.get(source_doc)\n\n            # Run QA evaluation\n            try:\n                qa_result = self.run_qa_eval(extracted_text, source_doc, gt_path, parse_latency)\n                qa_results.append(qa_result)\n                latency_str = \"\"\n                if qa_result.llm_latency_metrics:\n                    avg_lat = qa_result.llm_latency_metrics.average\n                    latency_str = f\" [avg LLM: {avg_lat:.2f}s]\"\n\n                print(f\"  QA: LLM judge pass: {qa_result.llm_judge_pass_rate:.1%}{latency_str}\")\n            except Exception as e:\n                print(f\"  Error: QA evaluation failed: {e}\")\n\n        # Aggregate results\n        aggregate = {}\n\n        if qa_results:\n            total_questions = sum(r.total_questions for r in qa_results)\n            total_llm_judge_passes = sum(\n                r.llm_judge_pass_rate * r.total_questions for r in qa_results\n            )\n\n            # Aggregate parse latency metrics\n            parse_latencies = [r.parse_latency_seconds for r in qa_results if r.parse_latency_seconds is not None]\n            parse_latency_metrics = LatencyMetrics(latencies=parse_latencies) if parse_latencies else None\n\n            # Aggregate LLM latency metrics across all documents\n            all_llm_latencies = []\n            for r in qa_results:\n                if r.llm_latency_metrics:\n                    all_llm_latencies.extend(r.llm_latency_metrics.latencies)\n            llm_latency_metrics = LatencyMetrics(latencies=all_llm_latencies) if all_llm_latencies else None\n\n            aggregate[\"qa\"] = {\n                \"total_documents\": len(qa_results),\n                \"total_questions\": total_questions,\n                \"overall_llm_judge_pass_rate\": total_llm_judge_passes / total_questions if total_questions > 0 else 0.0,\n                \"per_document_results\": [\n                    {\n                        \"file\": str(r.file_path),\n                        \"llm_judge_pass_rate\": r.llm_judge_pass_rate,\n                        \"total_questions\": r.total_questions,\n                        \"parse_latency_seconds\": r.parse_latency_seconds,\n                        \"llm_latency_metrics\": r.llm_latency_metrics.to_dict() if r.llm_latency_metrics else None\n                    }\n                    for r in qa_results\n                ]\n            }\n\n            if parse_latency_metrics:\n                aggregate[\"qa\"][\"parse_latency_metrics\"] = parse_latency_metrics.to_dict()\n\n            if llm_latency_metrics:\n                aggregate[\"qa\"][\"llm_latency_metrics\"] = llm_latency_metrics.to_dict()\n\n        # Save results if requested\n        if output_path:\n            # Save aggregate results\n            with open(f\"{output_path}.json\", \"w\") as f:\n                json.dump(aggregate, f, indent=2)\n            print(f\"\\nAggregate results saved to: {output_path}\")\n\n            # Save detailed results with extracted text for debugging\n            detailed_output_path = output_path.parent / f\"{output_path.stem}_detailed{output_path.suffix}\"\n            detailed_results = self._build_detailed_results(qa_results, extracted_texts)\n            with open(f\"{detailed_output_path}.json\", \"w\") as f:\n                json.dump(detailed_results, f, indent=2)\n            print(f\"Detailed results saved to: {detailed_output_path}\")\n\n            # Generate HTML report\n            try:\n                from liteparse_eval.report import HTMLReportGenerator\n\n                html_report_path = output_path.parent / f\"{output_path.stem}_report.html\"\n                generator = HTMLReportGenerator(\n                    detailed_results=detailed_results,\n                    ground_truth_dir=ground_truth_dir\n                )\n                generator.generate_report(html_report_path)\n                print(f\"HTML report saved to: {html_report_path}\")\n            except Exception as e:\n                print(f\"Warning: HTML report generation failed: {e}\")\n                # Don't fail the entire benchmark if HTML generation fails\n\n        return aggregate\n\n    def _build_detailed_results(\n        self,\n        qa_results: list[QAEvalResult],\n        extracted_texts: dict[str, str]\n    ) -> dict:\n        \"\"\"\n        Build detailed results including extracted text and individual test results.\n\n        Args:\n            qa_results: List of QA evaluation results\n            extracted_texts: Dictionary mapping file paths to extracted text\n\n        Returns:\n            Dictionary with detailed results for debugging\n        \"\"\"\n        detailed = {\"documents\": []}\n\n        # Create a mapping of file paths to results\n        qa_map = {str(r.file_path): r for r in qa_results}\n\n        # Combine results for each document\n        all_files = set(qa_map.keys())\n\n        for file_path in sorted(all_files):\n            doc_result = {\n                \"file\": file_path,\n                \"extracted_text\": extracted_texts.get(file_path, \"\")\n            }\n\n            # Add QA evaluation details\n            if file_path in qa_map:\n                qa_result = qa_map[file_path]\n                doc_result[\"qa_evaluation\"] = {\n                    \"llm_judge_pass_rate\": qa_result.llm_judge_pass_rate,\n                    \"total_questions\": qa_result.total_questions,\n                    \"parse_latency_seconds\": qa_result.parse_latency_seconds,\n                    \"llm_latency_metrics\": qa_result.llm_latency_metrics.to_dict() if qa_result.llm_latency_metrics else None,\n                    \"qa_pairs\": [\n                        {\n                            \"question\": qa.question,\n                            \"expected_answer\": qa.expected_answer,\n                            \"predicted_answer\": qa.predicted_answer,\n                            \"llm_judge_pass\": qa.llm_judge_pass,\n                        }\n                        for qa in qa_result.qa_results\n                    ]\n                }\n\n            detailed[\"documents\"].append(doc_result)\n\n        return detailed\n\n\ndef main():\n    \"\"\"Entry point of the benchmark framework.\"\"\"\n\n    parser = argparse.ArgumentParser(\n        description=\"Benchmark text extraction and LLM providers on document understanding tasks\"\n    )\n    parser.add_argument(\n        \"--data-dir\",\n        type=Path,\n        required=True,\n        help=\"Directory containing source documents\"\n    )\n    parser.add_argument(\n        \"--ground-truth-dir\",\n        type=Path,\n        required=True,\n        help=\"Directory containing ground truth JSON files\"\n    )\n    parser.add_argument(\n        \"--output\",\n        type=Path,\n        help=\"Path to save detailed benchmark results\"\n    )\n    parser.add_argument(\n        \"--parse-provider\",\n        type=str,\n        choices=[\"pymupdf\", \"pypdf\", \"markitdown\", \"liteparse\"],\n        default=\"liteparse\",\n        help=\"Parse provider to use for text extraction. (default: liteparse)\"\n    )\n    parser.add_argument(\n        \"--llm-provider\",\n        type=str,\n        choices=[\"anthropic\"],\n        default=\"anthropic\",\n        help=\"LLM provider to use. (default: anthropic)\"\n    )\n\n    args = parser.parse_args()\n\n    # Initialize parser provider\n    if args.parse_provider == \"pymupdf\":\n        parser_provider = PyMuPDFProvider()\n    elif args.parse_provider == \"pypdf\":\n        parser_provider = PyPDFProvider()\n    elif args.parse_provider == \"markitdown\":\n        parser_provider = MarkItDownProvider()\n    elif args.parse_provider == \"liteparse\":\n        parser_provider = LiteparseProvider()\n    else:\n        raise ValueError(\"Please specify a valid parser provider using --parse-provider\")\n\n    # Initialize LLM provider\n    if args.llm_provider == \"anthropic\":\n        llm_provider = AnthropicProvider()\n    else:\n        raise ValueError(\"Please specify a valid LLM provider using --llm-provider\")\n\n    # Use separate LLM judge provider\n    llm_judge_provider = AnthropicProvider(model=\"claude-haiku-4-5-20251001\")\n\n    benchmark = Benchmark(\n        parser_provider=parser_provider,\n        llm_provider=llm_provider,\n        llm_judge_provider=llm_judge_provider,\n    )\n\n    results = benchmark.run_full_benchmark(\n        data_dir=args.data_dir,\n        ground_truth_dir=args.ground_truth_dir,\n        output_path=args.output\n    )\n\n    print(\"\\n\" + \"=\"*60)\n    print(\"BENCHMARK RESULTS\")\n    print(\"=\"*60)\n\n    if \"qa\" in results:\n        print(f\"\\nQA Evaluation:\")\n        print(f\"  Overall LLM Judge Pass Rate: {results['qa']['overall_llm_judge_pass_rate']:.1%}\")\n        print(f\"  Total Questions: {results['qa']['total_questions']}\")\n\n\nif __name__ == \"__main__\":\n    exit(main())\n"
  },
  {
    "path": "dataset_eval_utils/src/liteparse_eval/processing.py",
    "content": "\"\"\"\nProcess PDFs and images to create a structured dataset using Anthropic's Claude with vision.\n\"\"\"\n\nimport base64\nimport json\nimport random\nfrom pathlib import Path\nfrom typing import List, Literal\n\nfrom anthropic import Anthropic\nfrom liteparse import LiteParse\nfrom pydantic import BaseModel, Field\n\n\n# Define the output schema using Pydantic-like structure\nclass QAPair(BaseModel):\n    question: str = Field(..., description=\"A question that can only be answered using information from the page.\")\n    answer: str = Field()\n\nclass PageAnnotation(BaseModel):\n    has_text: bool = Field(..., description=\"Whether the document contains readable text\")\n    document_type: Literal[\"academic_paper\", \"form\", \"invoice\", \"newspaper\", \"other\"] = Field(\n        ..., description=\"The type of document\"\n    )\n    layout_complexity: Literal[\"simple\", \"multi_column\", \"complex\"] = Field(\n        ..., description=\"The complexity of the document layout\"\n    )\n    qa_pairs: List[QAPair] = Field(\n        ...,\n        description=\"Question-answer pairs about the document\",\n        example=[{\"question\": \"What is the main topic?\", \"answer\": \"Sample Answer\"}]\n    )\n\n\ndef pdf_to_images(pdf_path: Path, dpi: int = 150) -> List[Path]:\n    \"\"\"\n    Convert a PDF to a list of image paths (one per page) using liteparse.\n\n    Args:\n        pdf_path: Path to the PDF file\n        dpi: DPI for rendering (default: 150)\n\n    Returns:\n        List of paths to generated images (one per page)\n    \"\"\"\n    parser = LiteParse()\n    result = parser.screenshot(pdf_path, dpi=dpi)\n\n    return [Path(s.image_path) for s in result.screenshots]\n\n    \ndef encode_image(image_path: Path) -> tuple[str, str]:\n    \"\"\"\n    Encode an image to base64 and determine its media type.\n\n    Args:\n        image_path: Path to the image file\n\n    Returns:\n        Tuple of (base64_encoded_data, media_type)\n    \"\"\"\n    with open(image_path, \"rb\") as image_file:\n        image_data = base64.standard_b64encode(image_file.read()).decode(\"utf-8\")\n\n    # Determine media type from extension\n    extension = image_path.suffix.lower()\n    media_type_map = {\n        \".jpg\": \"image/jpeg\",\n        \".jpeg\": \"image/jpeg\",\n        \".png\": \"image/png\",\n        \".gif\": \"image/gif\",\n        \".webp\": \"image/webp\"\n    }\n    media_type = media_type_map.get(extension, \"image/jpeg\")\n\n    return image_data, media_type\n\n\ndef analyze_image_with_claude(\n    client: Anthropic,\n    image_path: Path,\n    model: str = \"claude-sonnet-4-5-20250929\"\n) -> PageAnnotation | None:\n    \"\"\"\n    Analyze an image using Claude with structured outputs.\n\n    Args:\n        client: Anthropic client\n        image_path: Path to the image to analyze\n        model: Model to use for analysis\n\n    Returns:\n        Structured analysis result as a dictionary\n    \"\"\"\n    image_data, media_type = encode_image(image_path)\n\n    prompt = \"\"\"Analyze this document image and provide a structured analysis.\n\nExtract:\n1. Whether it contains readable text\n2. The document type (academic_paper, form, invoice, newspaper, or other)\n3. Layout complexity (simple, multi_column, or complex)\n4. Generate 3-5 question-answer pairs about the document content\n\nBe thorough and accurate in your analysis. This data will be used in a document parsing benchmark (LLM-as-a-judge on QA responses), so extracted data should be interesting, diverse, and sometimes challenging.\"\"\"\n\n    # With .parse() - can pass Pydantic model directly\n    response = client.beta.messages.parse(\n        model=model,\n        max_tokens=8192,\n        betas=[\"structured-outputs-2025-11-13\"],\n        messages=[\n            {\n                \"role\": \"user\",\n                \"content\": [\n                    {\n                        \"type\": \"image\",\n                        \"source\": {\n                            \"type\": \"base64\",\n                            \"media_type\": media_type,\n                            \"data\": image_data,\n                        },\n                    },\n                    {\n                        \"type\": \"text\",\n                        \"text\": prompt\n                    }\n                ],\n            }\n        ],\n        output_format=PageAnnotation,\n    )\n\n    return response.parsed_output\n\n\ndef process_file(\n    client: Anthropic,\n    file_path: Path,\n    output_dir: Path,\n    model: str = \"claude-sonnet-4-5-20250929\"\n) -> None:\n    \"\"\"\n    Process a single file (PDF or image) and save results.\n\n    Args:\n        client: Anthropic client\n        file_path: Path to the file to process\n        output_dir: Directory to save output JSON files\n        model: Model to use for analysis\n    \"\"\"\n    print(f\"Processing: {file_path}\")\n\n    # Handle PDFs vs images\n    if file_path.suffix.lower() == \".pdf\":\n        try:\n            image_paths = pdf_to_images(file_path)\n        except NotImplementedError:\n            print(f\"  Skipping PDF (conversion not implemented): {file_path}\")\n            return\n    else:\n        # Single image file\n        image_paths = [file_path]\n\n    # Process each page/image\n    for page_num, image_path in enumerate(image_paths, start=1):\n        try:\n            print(f\"  Analyzing page {page_num}/{len(image_paths)}...\")\n            result = analyze_image_with_claude(client, image_path, model)\n\n            if result is None:\n                print(f\"  ✗ No results for page {page_num} in {file_path}\")\n                continue\n\n            # Create output filename\n            if len(image_paths) > 1:\n                # Multi-page PDF\n                output_filename = f\"{file_path.stem}_page_{page_num:03d}.json\"\n            else:\n                # Single image\n                output_filename = f\"{file_path.stem}.json\"\n\n            output_path = output_dir / output_filename\n\n            # Save result\n            with open(output_path, \"w\", encoding=\"utf-8\") as f:\n                json.dump(result.model_dump(), f, indent=2, ensure_ascii=False)\n\n            print(f\"  ✓ Saved: {output_path}\")\n\n        except Exception as e:\n            print(f\"  ✗ Error processing page {page_num}: {e}\")\n\n\ndef find_documents(input_dir: Path) -> List[Path]:\n    \"\"\"\n    Find all PDF and image files in a directory (recursively).\n\n    Args:\n        input_dir: Directory to search\n\n    Returns:\n        List of paths to document files\n    \"\"\"\n    supported_extensions = {\".pdf\", \".jpg\", \".jpeg\", \".png\", \".gif\", \".webp\"}\n    documents = []\n\n    for ext in supported_extensions:\n        documents.extend(input_dir.rglob(f\"*{ext}\"))\n        documents.extend(input_dir.rglob(f\"*{ext.upper()}\"))\n\n    return sorted(set(documents))\n\n\ndef main():\n    \"\"\"Main entry point.\"\"\"\n    import argparse\n\n    parser = argparse.ArgumentParser(\n        description=\"Process PDFs and images to create a structured dataset\"\n    )\n    parser.add_argument(\n        \"input_dir\",\n        type=Path,\n        help=\"Directory containing PDFs and/or images to process\"\n    )\n    parser.add_argument(\n        \"--output-dir\",\n        type=Path,\n        default=Path(\"output\"),\n        help=\"Directory to save output JSON files (default: ./output)\"\n    )\n    parser.add_argument(\n        \"--model\",\n        type=str,\n        default=\"claude-sonnet-4-5-20250929\",\n        help=\"Claude model to use (default: claude-sonnet-4-5-20250929)\"\n    )\n    parser.add_argument(\n        \"--api-key\",\n        type=str,\n        help=\"Anthropic API key (or set ANTHROPIC_API_KEY environment variable)\"\n    )\n\n    args = parser.parse_args()\n\n    # Validate input directory\n    if not args.input_dir.exists():\n        print(f\"Error: Input directory does not exist: {args.input_dir}\")\n        return 1\n\n    # Create output directory\n    args.output_dir.mkdir(parents=True, exist_ok=True)\n\n    # Initialize Anthropic client\n    client = Anthropic(api_key=args.api_key) if args.api_key else Anthropic()\n\n    # Find all documents\n    documents = find_documents(args.input_dir)\n\n    if not documents:\n        print(f\"No documents found in {args.input_dir}\")\n        return 1\n\n\n    documents = random.sample(documents, 50)\n    print(f\"Found {len(documents)} document(s) to process\\n\")\n\n    # Process each document\n    for i, doc_path in enumerate(documents, start=1):\n        print(f\"\\n[{i}/{len(documents)}]\")\n        process_file(client, doc_path, args.output_dir, args.model)\n\n    print(f\"\\n✓ Complete! Results saved to: {args.output_dir}\")\n    return 0\n\n\nif __name__ == \"__main__\":\n    exit(main())\n"
  },
  {
    "path": "dataset_eval_utils/src/liteparse_eval/providers/__init__.py",
    "content": "from .llm import LLMProvider, AnthropicProvider, QA_PROMPT\nfrom .parsers import (\n    ParserProvider,\n    LiteparseProvider,\n    MarkItDownProvider,\n    PyMuPDFProvider,\n    PyPDFProvider,\n)\n\n__all__ = [\n    \"LLMProvider\",\n    \"AnthropicProvider\",\n    \"QA_PROMPT\",\n    \"ParserProvider\",\n    \"LiteparseProvider\",\n    \"MarkItDownProvider\",\n    \"PyMuPDFProvider\",\n    \"PyPDFProvider\",\n]\n"
  },
  {
    "path": "dataset_eval_utils/src/liteparse_eval/providers/llm/__init__.py",
    "content": "from .base import LLMProvider, QA_PROMPT\nfrom .anthropic import AnthropicProvider\n\n__all__ = [\"LLMProvider\", \"AnthropicProvider\", \"QA_PROMPT\"]\n"
  },
  {
    "path": "dataset_eval_utils/src/liteparse_eval/providers/llm/anthropic.py",
    "content": "from anthropic import Anthropic\n\nfrom .base import LLMProvider, QA_PROMPT, JUDGE_PROMPT\n\n\nclass AnthropicProvider(LLMProvider):\n    \"\"\"\n    LLM provider using Anthropic for QA.\n    \"\"\"\n\n    def __init__(self, api_key: str = None, model: str = \"claude-sonnet-4-5-20250929\"):\n        \"\"\"\n        Initialize Anthropic QA provider.\n\n        Args:\n            api_key: Anthropic API key (or use ANTHROPIC_API_KEY env var)\n            model: Claude model to use\n        \"\"\"\n\n        self.client = Anthropic(api_key=api_key, max_retries=100, timeout=10000)\n        self.model = model\n\n    def answer_question(self, ocr_text: str, question: str) -> str:\n        \"\"\"Answer a question about an image using Claude.\"\"\"\n\n        # Call Claude\n        response = self.client.messages.create(\n            model=self.model,\n            max_tokens=1024,\n            messages=[\n                {\n                    \"role\": \"user\",\n                    \"content\": QA_PROMPT.format(ocr_text=ocr_text, question=question),\n                }\n            ],\n            timeout=10000,\n        )\n        if not response.content or len(response.content) == 0:\n            raise ValueError(\"No content returned from Anthropic response\")\n        \n        return response.content[0].text\n\n    def evaluate_answer(self, question: str, expected_answer: str, predicted_answer: str) -> bool:\n        \"\"\"\n        Evaluate whether the predicted answer is correct compared to the expected answer using an LLM judge.\n        \"\"\"\n\n        # Call the LLM judge\n        judge_prompt = JUDGE_PROMPT.format(\n            question=question,\n            expected_answer=expected_answer,\n            predicted_answer=predicted_answer,\n        )\n\n        response = self.client.messages.create(\n            model=self.model,\n            max_tokens=256,\n            messages=[\n                {\n                    \"role\": \"user\",\n                    \"content\": judge_prompt,\n                }\n            ],\n            timeout=10000,\n        )\n        if not response.content or len(response.content) == 0:\n            # If the judge fails to respond, we can choose to be lenient and pass the answer\n            return True  \n\n        # Check if the response is \"<pass>\" or \"<fail>\"\n        resp_text = response.content[0].text.strip()\n\n        resp_text_lower = resp_text.lower()\n        return \"<pass\" in resp_text_lower and \"<fail\" not in resp_text_lower\n"
  },
  {
    "path": "dataset_eval_utils/src/liteparse_eval/providers/llm/base.py",
    "content": "from abc import ABC, abstractmethod\nfrom pathlib import Path\n\nQA_PROMPT = \"<document>{ocr_text}</document>\\n\\nAnswer the following question about the document. Be as concise and accurate and possible, pulling from the exact text. If the document does not contain the answer, response with 'not found'.\\n\\nQuestion: {question}\"\nJUDGE_PROMPT = \"\"\"You are evaluating whether two answers to a question are semantically equivalent.\n\n<question>{question}</question>\n\n<expected_answer>{expected_answer}</expected_answer>\n\n<predicted_answer>{predicted_answer}</predicted_answer>\n\nDo these answers convey the same information? Consider:\n1. Are the answers semantically equivalent, even if wording differs?\n2. Is the meaning preserved even if wording differs?\n3. Some answers rely on the question for context, so ensure that the predicted answer is correct in the context of the question, even if it is not verbatim the same as the expected answer.\n4. If the predicted answer says \"not found\" or similar, it should only pass if the expected answer also indicates the information is not present.\n\nRespond with \"<pass>{{short explanation}}</pass>\" if the answers are semantically equivalent, or \"<fail>{{short explanation}}</fail>\" if they are not. The explanation should be concise, ideally one sentence, and should justify the pass/fail decision based on the criteria above.\"\"\"\n\n\nclass LLMProvider(ABC):\n    \"\"\"Abstract base class for LLM providers.\"\"\"\n\n    @abstractmethod\n    def answer_question(self, image_path: Path, question: str) -> str:\n        \"\"\"\n        Answer a question about an image.\n\n        Args:\n            image_path: Path to the image file\n            question: Question to answer\n\n        Returns:\n            Answer as a string\n        \"\"\"\n        pass\n\n    @abstractmethod\n    def evaluate_answer(self, question: str, expected_answer: str, predicted_answer: str) -> bool:\n        \"\"\"\n        Evaluate whether the predicted answer is correct compared to the expected answer.\n\n        Args:\n            expected_answer: The ground truth answer\n            predicted_answer: The answer generated by the LLM\n\n        Returns:\n            True if the predicted answer is correct, False otherwise\n        \"\"\"\n        pass\n"
  },
  {
    "path": "dataset_eval_utils/src/liteparse_eval/providers/parsers/__init__.py",
    "content": "from .base import ParserProvider\nfrom .liteparse import LiteparseProvider\nfrom .markitdown import MarkItDownProvider\nfrom .pymupdf import PyMuPDFProvider\nfrom .pypdf import PyPDFProvider\n\n__all__ = [\n    \"ParserProvider\",\n    \"LiteparseProvider\",\n    \"MarkItDownProvider\",\n    \"PyMuPDFProvider\",\n    \"PyPDFProvider\",\n]\n"
  },
  {
    "path": "dataset_eval_utils/src/liteparse_eval/providers/parsers/base.py",
    "content": "from abc import ABC, abstractmethod\nfrom pathlib import Path\n\n\nclass ParserProvider(ABC):\n    \"\"\"Abstract base class for text extraction/parsing providers.\"\"\"\n\n    @abstractmethod\n    def extract_text(self, file_path: Path) -> str:\n        \"\"\"\n        Extract text from a document.\n\n        Args:\n            file_path: Path to the document file\n\n        Returns:\n            Extracted text as a single string\n        \"\"\"\n        pass\n\n    def extract_text_batch(self, file_paths: list[Path]) -> dict[Path, str]:\n        \"\"\"\n        Extract text from multiple documents in batch.\n\n        Override this method for providers that support native batch processing.\n        The default implementation processes files sequentially.\n\n        Args:\n            file_paths: List of paths to document files\n\n        Returns:\n            Dictionary mapping file paths to extracted text\n        \"\"\"\n        results = {}\n        for file_path in file_paths:\n            results[file_path] = self.extract_text(file_path)\n        return results\n"
  },
  {
    "path": "dataset_eval_utils/src/liteparse_eval/providers/parsers/liteparse.py",
    "content": "from pathlib import Path\nfrom typing import Optional\n\nfrom liteparse import LiteParse\n\nfrom .base import ParserProvider\n\n\nclass LiteparseProvider(ParserProvider):\n    \"\"\"\n    Parser provider using the liteparse Python wrapper.\n\n    This provider uses the liteparse library for PDF text extraction.\n    \"\"\"\n\n    def __init__(\n        self,\n        ocr_enabled: bool = False,\n        ocr_server_url: Optional[str] = None,\n        ocr_language: str = \"en\",\n        max_pages: int = 1000,\n        dpi: int = 150,\n        precise_bounding_box: bool = True,\n        skip_diagonal_text: bool = False,\n        preserve_very_small_text: bool = False,\n        cli_path: Optional[str] = None,\n    ):\n        \"\"\"\n        Initialize the liteparse provider.\n\n        Args:\n            ocr_enabled: Whether to enable OCR for scanned documents\n            ocr_server_url: URL of HTTP OCR server (uses Tesseract if not provided)\n            ocr_language: Language code for OCR (e.g., \"en\", \"fr\", \"de\")\n            max_pages: Maximum number of pages to parse\n            dpi: DPI for rendering (affects OCR quality)\n            precise_bounding_box: Whether to compute precise bounding boxes\n            skip_diagonal_text: Whether to skip diagonal text\n            preserve_very_small_text: Whether to preserve very small text\n            cli_path: Custom path to liteparse CLI (auto-detected if not provided)\n        \"\"\"\n        self.parser = LiteParse(cli_path=cli_path)\n        self.ocr_enabled = ocr_enabled\n        self.ocr_server_url = ocr_server_url\n        self.ocr_language = ocr_language\n        self.max_pages = max_pages\n        self.dpi = dpi\n        self.precise_bounding_box = precise_bounding_box\n        self.skip_diagonal_text = skip_diagonal_text\n        self.preserve_very_small_text = preserve_very_small_text\n\n    def extract_text(self, file_path: Path) -> str:\n        \"\"\"Extract text from a document using liteparse.\"\"\"\n        result = self.parser.parse(\n            file_path,\n            ocr_enabled=self.ocr_enabled,\n            ocr_server_url=self.ocr_server_url,\n            ocr_language=self.ocr_language,\n            max_pages=self.max_pages,\n            dpi=self.dpi,\n            precise_bounding_box=self.precise_bounding_box,\n            skip_diagonal_text=self.skip_diagonal_text,\n            preserve_very_small_text=self.preserve_very_small_text,\n        )\n        return result.text\n"
  },
  {
    "path": "dataset_eval_utils/src/liteparse_eval/providers/parsers/markitdown.py",
    "content": "from pathlib import Path\n\nfrom markitdown import MarkItDown\n\nfrom .base import ParserProvider\n\n\nclass MarkItDownProvider(ParserProvider):\n    \"\"\"\n    Parse provider using MarkItDown.\n\n    Install with: pip install markitdown\n    \"\"\"\n\n    def __init__(self, config: dict | None = None):\n        \"\"\"\n        Initialize the parse provider.\n\n        Args:\n            config: Configuration dict parameters for MarkItDown\n        \"\"\"\n        self.config = config or {}\n        self.markitdown = MarkItDown(**self.config)\n\n    def extract_text(self, file_path: Path) -> str:\n        \"\"\"Extract text from a document using MarkItDown.\"\"\"\n        result = self.markitdown.convert(str(file_path))\n        return result.text_content\n"
  },
  {
    "path": "dataset_eval_utils/src/liteparse_eval/providers/parsers/pymupdf.py",
    "content": "from pathlib import Path\n\nimport fitz  # PyMuPDF\n\nfrom .base import ParserProvider\n\n\nclass PyMuPDFProvider(ParserProvider):\n    \"\"\"\n    Parse provider using PyMuPDF.\n\n    Install with: pip install pymupdf\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Initialize the parse provider.\"\"\"\n        pass\n\n    def extract_text(self, file_path: Path) -> str:\n        \"\"\"Extract text from a document using PyMuPDF.\"\"\"\n        doc = fitz.open(str(file_path))\n        text = \"\\n\\n\".join(page.get_text() for page in doc)\n        return text\n"
  },
  {
    "path": "dataset_eval_utils/src/liteparse_eval/providers/parsers/pypdf.py",
    "content": "from pathlib import Path\n\nimport pypdf\n\nfrom .base import ParserProvider\n\n\nclass PyPDFProvider(ParserProvider):\n    \"\"\"\n    Parse provider using PyPDF.\n\n    Install with: pip install pypdf\n    \"\"\"\n\n    def __init__(self, config: dict | None = None):\n        \"\"\"\n        Initialize the parse provider.\n\n        Args:\n            config: Configuration dict parameters for PyPDF\n        \"\"\"\n        self.config = config or {}\n\n    def extract_text(self, file_path: Path) -> str:\n        \"\"\"Extract text from a document using PyPDF.\"\"\"\n        result = pypdf.PdfReader(str(file_path), **self.config)\n        text = \"\\n\\n\".join(page.extract_text() for page in result.pages)\n        return text\n"
  },
  {
    "path": "dataset_eval_utils/src/liteparse_eval/report.py",
    "content": "\"\"\"HTML report generation for text extraction evaluation results.\"\"\"\n\nimport base64\nimport html\nimport io\nfrom datetime import datetime\nfrom pathlib import Path\n\nimport fitz  # PyMuPDF\n\ntry:\n    from PIL import Image\n    HAS_PIL = True\nexcept ImportError:\n    HAS_PIL = False\n\n\nclass HTMLReportGenerator:\n    \"\"\"Generate HTML reports from text extraction evaluation results.\"\"\"\n\n    def __init__(self, detailed_results: dict, ground_truth_dir: Path):\n        \"\"\"\n        Initialize the HTML report generator.\n\n        Args:\n            detailed_results: Dictionary containing detailed evaluation results\n            ground_truth_dir: Path to the directory containing ground truth JSON files\n        \"\"\"\n        self.detailed_results = detailed_results\n        self.ground_truth_dir = ground_truth_dir\n        self.documents = detailed_results.get(\"documents\", [])\n\n    def generate_report(self, output_path: Path) -> None:\n        \"\"\"\n        Generate complete HTML report and save to file.\n\n        Args:\n            output_path: Path where the HTML report will be saved\n        \"\"\"\n        html_content = self._build_html()\n        output_path.write_text(html_content, encoding=\"utf-8\")\n\n    def _build_html(self) -> str:\n        \"\"\"Build the complete HTML document.\"\"\"\n        css = self._generate_css()\n        summary = self._generate_summary_html()\n        navigation = self._generate_navigation_html()\n        documents_html = self._generate_all_documents_html()\n\n        return f\"\"\"<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Parsing Evaluation Report - {datetime.now().strftime('%Y-%m-%d %H:%M')}</title>\n    <style>\n{css}\n    </style>\n</head>\n<body>\n    {navigation}\n    {summary}\n    {documents_html}\n</body>\n</html>\"\"\"\n\n    def _generate_css(self) -> str:\n        \"\"\"Generate CSS styles for the report.\"\"\"\n        return \"\"\"        body {\n            font-family: system-ui, -apple-system, sans-serif;\n            margin: 0;\n            padding: 0;\n            background: #f5f5f5;\n        }\n        .container {\n            max-width: 1400px;\n            margin: 0 auto;\n            padding: 20px;\n        }\n        nav {\n            position: sticky;\n            top: 0;\n            background: #fff;\n            padding: 15px 20px;\n            border-bottom: 2px solid #ddd;\n            z-index: 100;\n            box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n        }\n        nav h2 {\n            margin: 0 0 10px 0;\n            font-size: 1.25em;\n        }\n        .nav-list {\n            display: grid;\n            grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n            gap: 10px;\n            max-height: 0;\n            overflow: hidden;\n            transition: max-height 0.3s ease;\n        }\n        .nav-list.expanded {\n            max-height: 500px;\n            overflow-y: auto;\n        }\n        .toggle-nav {\n            background: #3b82f6;\n            color: white;\n            border: none;\n            padding: 8px 16px;\n            border-radius: 4px;\n            cursor: pointer;\n            font-size: 0.9em;\n        }\n        .toggle-nav:hover {\n            background: #2563eb;\n        }\n        .nav-item {\n            padding: 8px 12px;\n            background: #f9fafb;\n            border-radius: 4px;\n            text-decoration: none;\n            color: #1f2937;\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            border-left: 4px solid #d1d5db;\n        }\n        .nav-item:hover {\n            background: #e5e7eb;\n        }\n        .nav-item.good {\n            border-left-color: #22c55e;\n        }\n        .nav-item.warning {\n            border-left-color: #f59e0b;\n        }\n        .nav-item.poor {\n            border-left-color: #ef4444;\n        }\n        .nav-item-metrics {\n            font-size: 0.85em;\n            color: #6b7280;\n        }\n        .summary {\n            background: #fff;\n            padding: 30px;\n            margin: 20px 0;\n            border-radius: 8px;\n            box-shadow: 0 1px 3px rgba(0,0,0,0.1);\n        }\n        .summary h1 {\n            margin: 0 0 20px 0;\n            color: #1f2937;\n        }\n        .metrics {\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n            gap: 20px;\n            margin: 20px 0;\n        }\n        .metric {\n            background: #f9fafb;\n            border: 1px solid #e5e7eb;\n            padding: 20px;\n            border-radius: 8px;\n        }\n        .metric-label {\n            font-size: 0.9em;\n            color: #6b7280;\n            margin-bottom: 8px;\n        }\n        .metric-value {\n            font-size: 2em;\n            font-weight: bold;\n            margin-bottom: 5px;\n        }\n        .metric-value.good {\n            color: #22c55e;\n        }\n        .metric-value.warning {\n            color: #f59e0b;\n        }\n        .metric-value.poor {\n            color: #ef4444;\n        }\n        .document {\n            background: #fff;\n            border: 1px solid #e5e7eb;\n            margin: 20px 0;\n            padding: 30px;\n            border-radius: 8px;\n            box-shadow: 0 1px 3px rgba(0,0,0,0.1);\n        }\n        .document-header {\n            display: flex;\n            justify-content: space-between;\n            align-items: flex-start;\n            margin-bottom: 20px;\n            padding-bottom: 15px;\n            border-bottom: 2px solid #e5e7eb;\n        }\n        .document-title {\n            font-size: 1.5em;\n            font-weight: bold;\n            color: #1f2937;\n            word-break: break-all;\n        }\n        .edit-link {\n            display: inline-block;\n            padding: 8px 16px;\n            background: #3b82f6;\n            color: white;\n            text-decoration: none;\n            border-radius: 4px;\n            font-size: 0.9em;\n            white-space: nowrap;\n        }\n        .edit-link:hover {\n            background: #2563eb;\n        }\n        .section {\n            margin: 30px 0;\n        }\n        .section-title {\n            font-size: 1.25em;\n            font-weight: bold;\n            margin: 0 0 15px 0;\n            color: #374151;\n        }\n        .pdf-preview {\n            max-width: 100%;\n            border: 1px solid #d1d5db;\n            border-radius: 4px;\n            box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n        }\n        .pdf-error {\n            background: #fee2e2;\n            border: 1px solid #fecaca;\n            padding: 20px;\n            border-radius: 4px;\n            color: #991b1b;\n        }\n        .doc-text {\n            background: #f9fafb;\n            border: 1px solid #e5e7eb;\n            padding: 20px;\n            border-radius: 4px;\n            white-space: pre-wrap;\n            font-family: 'Courier New', monospace;\n            font-size: 0.9em;\n            max-height: 400px;\n            overflow-y: auto;\n            line-height: 1.5;\n        }\n        .qa-pairs {\n            display: flex;\n            flex-direction: column;\n            gap: 15px;\n        }\n        .qa-item {\n            padding: 20px;\n            background: #f9fafb;\n            border-radius: 4px;\n            border-left: 4px solid;\n        }\n        .qa-item.pass {\n            border-left-color: #22c55e;\n        }\n        .qa-item.fail {\n            border-left-color: #ef4444;\n        }\n        .qa-question {\n            font-weight: bold;\n            margin-bottom: 12px;\n            color: #1f2937;\n        }\n        .qa-answer {\n            margin: 8px 0;\n            padding: 10px;\n            background: white;\n            border-radius: 4px;\n        }\n        .qa-label {\n            font-size: 0.85em;\n            color: #6b7280;\n            margin-bottom: 4px;\n        }\n        .qa-score {\n            font-weight: bold;\n            font-size: 1.1em;\n            margin-top: 10px;\n        }\n        .score-badge {\n            display: inline-block;\n            padding: 4px 8px;\n            border-radius: 4px;\n            font-size: 0.85em;\n            font-weight: bold;\n        }\n        .score-badge.good {\n            background: #dcfce7;\n            color: #166534;\n        }\n        .score-badge.warning {\n            background: #fef3c7;\n            color: #92400e;\n        }\n        .score-badge.poor {\n            background: #fee2e2;\n            color: #991b1b;\n        }\"\"\"\n\n    def _generate_summary_html(self) -> str:\n        \"\"\"Generate aggregate metrics summary section.\"\"\"\n        total_docs = len(self.documents)\n\n        # Calculate aggregate QA metrics\n        total_llm_judge_pass = 0\n        qa_count = 0\n        parse_latencies = []\n        all_llm_latencies = []\n\n        for doc in self.documents:\n            qa_eval = doc.get(\"qa_evaluation\", {})\n            if qa_eval:\n                llm_judge_rate = qa_eval.get(\"llm_judge_pass_rate\", 0)\n                total_llm_judge_pass += llm_judge_rate\n                qa_count += 1\n\n                parse_lat = qa_eval.get(\"parse_latency_seconds\")\n                if parse_lat is not None:\n                    parse_latencies.append(parse_lat)\n\n                llm_metrics = qa_eval.get(\"llm_latency_metrics\")\n                if llm_metrics:\n                    all_llm_latencies.extend(llm_metrics.get(\"individual_latencies\", []))\n\n        avg_llm_judge_pass = total_llm_judge_pass / qa_count if qa_count > 0 else 0\n        judge_class = self._get_metric_class(avg_llm_judge_pass)\n\n        # Generate latency metrics HTML\n        latency_metrics_html = \"\"\n        if parse_latencies:\n            avg_parse_lat = sum(parse_latencies) / len(parse_latencies)\n            latency_metrics_html += f\"\"\"                <div class=\"metric\">\n                    <div class=\"metric-label\">Parse Latency (Avg)</div>\n                    <div class=\"metric-value\">{avg_parse_lat:.2f}s</div>\n                    <div class=\"metric-label\">min: {min(parse_latencies):.2f}s, max: {max(parse_latencies):.2f}s</div>\n                </div>\"\"\"\n\n        if all_llm_latencies:\n            avg_llm_lat = sum(all_llm_latencies) / len(all_llm_latencies)\n            latency_metrics_html += f\"\"\"                <div class=\"metric\">\n                    <div class=\"metric-label\">LLM Latency (Avg per call)</div>\n                    <div class=\"metric-value\">{avg_llm_lat:.2f}s</div>\n                    <div class=\"metric-label\">min: {min(all_llm_latencies):.2f}s, max: {max(all_llm_latencies):.2f}s</div>\n                </div>\"\"\"\n\n        return f\"\"\"    <div class=\"container\">\n        <div class=\"summary\">\n            <h1>QA Evaluation Report</h1>\n            <p>Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>\n            <div class=\"metrics\">\n                <div class=\"metric\">\n                    <div class=\"metric-label\">Total Documents</div>\n                    <div class=\"metric-value\">{total_docs}</div>\n                </div>\n                <div class=\"metric\">\n                    <div class=\"metric-label\">LLM Judge Pass Rate</div>\n                    <div class=\"metric-value {judge_class}\">{avg_llm_judge_pass:.1%}</div>\n                    <div class=\"metric-label\">Across {qa_count} documents</div>\n                </div>\n{latency_metrics_html}\n            </div>\n        </div>\n    </div>\"\"\"\n\n    def _generate_navigation_html(self) -> str:\n        \"\"\"Generate navigation with anchors to each document.\"\"\"\n        nav_items = []\n        for idx, doc in enumerate(self.documents):\n            filename = Path(doc[\"file\"]).name\n            qa_eval = doc.get(\"qa_evaluation\", {})\n\n            judge_pass = qa_eval.get(\"llm_judge_pass_rate\", 0)\n            nav_class = self._get_metric_class(judge_pass)\n\n            metrics_text = f\"Judge Pass: {judge_pass:.0%}\"\n\n            nav_items.append(\n                f'            <a href=\"#doc-{idx}\" class=\"nav-item {nav_class}\">'\n                f'<span>{html.escape(filename)}</span>'\n                f'<span class=\"nav-item-metrics\">{metrics_text}</span>'\n                f'</a>'\n            )\n\n        nav_list = \"\\n\".join(nav_items)\n\n        return f\"\"\"    <nav>\n        <div class=\"container\">\n            <h2>Document Navigation ({len(self.documents)} documents)</h2>\n            <button class=\"toggle-nav\" onclick=\"this.nextElementSibling.classList.toggle('expanded')\">\n                Toggle Navigation\n            </button>\n            <div class=\"nav-list\">\n{nav_list}\n            </div>\n        </div>\n    </nav>\"\"\"\n\n    def _generate_all_documents_html(self) -> str:\n        \"\"\"Generate HTML for all documents.\"\"\"\n        docs_html = []\n        for idx, doc in enumerate(self.documents):\n            docs_html.append(self._generate_document_html(doc, idx))\n\n        return f\"\"\"    <div class=\"container\">\n{chr(10).join(docs_html)}\n    </div>\"\"\"\n\n    def _generate_document_html(self, doc: dict, index: int) -> str:\n        \"\"\"Generate HTML for single document with all evaluations.\"\"\"\n        filename = Path(doc[\"file\"]).name\n        pdf_path = Path(doc[\"file\"])\n\n        # Generate VS Code link\n        vscode_link = self._generate_vscode_link(doc[\"file\"])\n        edit_button = f'<a href=\"{vscode_link}\" class=\"edit-link\">Edit Ground Truth</a>' if vscode_link else ''\n\n        # Generate PDF preview\n        pdf_preview_html = self._generate_pdf_preview_html(pdf_path)\n\n        extracted_text = doc.get(\"extracted_text\")\n        extracted_text_html = f'<pre class=\"doc-text\">{html.escape(extracted_text)}</pre>'\n\n        # Generate QA results\n        qa_html = self._generate_qa_html(doc.get(\"qa_evaluation\", {}))\n\n        return f\"\"\"        <div class=\"document\" id=\"doc-{index}\">\n            <div class=\"document-header\">\n                <div class=\"document-title\">{html.escape(filename)}</div>\n                {edit_button}\n            </div>\n\n            <div class=\"section\">\n                <h3 class=\"section-title\">PDF Preview</h3>\n                {pdf_preview_html}\n            </div>\n\n            <div class=\"section\">\n                <h3 class=\"section-title\">Extracted Text</h3>\n                {extracted_text_html}\n            </div>\n\n            <div class=\"section\">\n                <h3 class=\"section-title\">QA Evaluation</h3>\n                {qa_html}\n            </div>\n        </div>\"\"\"\n\n    def _generate_pdf_preview_html(self, pdf_path: Path) -> str:\n        \"\"\"Generate PDF preview HTML with base64 encoded image.\"\"\"\n        try:\n            base64_image = self._pdf_to_base64_image(pdf_path)\n            return f'<img src=\"{base64_image}\" alt=\"PDF Preview\" class=\"pdf-preview\">'\n        except Exception as e:\n            return f'<div class=\"pdf-error\">Failed to load PDF preview: {html.escape(str(e))}</div>'\n\n    def _generate_qa_html(self, qa_eval: dict) -> str:\n        \"\"\"Generate HTML for QA evaluation results.\"\"\"\n        if not qa_eval:\n            return '<p>No QA evaluation data available.</p>'\n\n        llm_judge_pass_rate = qa_eval.get(\"llm_judge_pass_rate\", 0)\n        total_questions = qa_eval.get(\"total_questions\", 0)\n        parse_latency = qa_eval.get(\"parse_latency_seconds\")\n        llm_metrics = qa_eval.get(\"llm_latency_metrics\")\n\n        judge_class = self._get_metric_class(llm_judge_pass_rate)\n\n        latency_text = \"\"\n        if parse_latency is not None:\n            latency_text += f'<p><strong>Parse Latency:</strong> {parse_latency:.2f}s</p>'\n\n        if llm_metrics:\n            avg_lat = llm_metrics.get(\"average_seconds\", 0)\n            min_lat = llm_metrics.get(\"min_seconds\", 0)\n            max_lat = llm_metrics.get(\"max_seconds\", 0)\n            stddev_lat = llm_metrics.get(\"stddev_seconds\", 0)\n            latency_text += f'<p><strong>LLM Latency:</strong> avg: {avg_lat:.2f}s, min: {min_lat:.2f}s, max: {max_lat:.2f}s, stddev: {stddev_lat:.2f}s</p>'\n\n        summary = f'<p><strong>LLM Judge Pass Rate:</strong> <span class=\"score-badge {judge_class}\">{llm_judge_pass_rate:.1%}</span> (across {total_questions} questions)</p>{latency_text}'\n\n        qa_pairs = qa_eval.get(\"qa_pairs\", [])\n        if not qa_pairs:\n            return summary + '<p>No QA pairs to display.</p>'\n\n        qa_items = []\n        for qa in qa_pairs:\n            llm_judge_pass = qa.get(\"llm_judge_pass\", False)\n\n            item_class = \"pass\" if llm_judge_pass else \"fail\"\n            badge_class = \"good\" if llm_judge_pass else \"poor\"\n            badge_text = \"PASS\" if llm_judge_pass else \"FAIL\"\n\n            question = html.escape(qa.get(\"question\", \"\"))\n            expected = html.escape(qa.get(\"expected_answer\", \"\"))\n            predicted = html.escape(qa.get(\"predicted_answer\", \"\"))\n\n            qa_items.append(\n                f'                <div class=\"qa-item {item_class}\">'\n                f'<div class=\"qa-question\">Q: {question}</div>'\n                f'<div class=\"qa-answer\">'\n                f'<div class=\"qa-label\">Expected Answer:</div>'\n                f'{expected}'\n                f'</div>'\n                f'<div class=\"qa-answer\">'\n                f'<div class=\"qa-label\">Predicted Answer:</div>'\n                f'{predicted}'\n                f'</div>'\n                f'<div class=\"qa-score\">'\n                f'<span class=\"score-badge {badge_class}\">LLM Judge: {badge_text}</span>'\n                f'</div>'\n                f'</div>'\n            )\n\n        qa_html = \"\\n\".join(qa_items)\n\n        return f\"\"\"{summary}\n            <div class=\"qa-pairs\">\n{qa_html}\n            </div>\"\"\"\n\n    def _pdf_to_base64_image(self, pdf_path: Path, dpi: int = 72) -> str:\n        \"\"\"\n        Convert first page of PDF to base64-encoded image.\n\n        Uses JPEG compression if PIL is available, otherwise PNG.\n\n        Args:\n            pdf_path: Path to the PDF file\n            dpi: Resolution for rendering (default 72)\n\n        Returns:\n            Base64-encoded image as data URL\n\n        Raises:\n            Exception: If PDF cannot be opened or converted\n        \"\"\"\n        doc = fitz.open(str(pdf_path))\n        try:\n            page = doc[0]  # First page only\n\n            # Render to pixmap at specified DPI\n            mat = fitz.Matrix(dpi / 72, dpi / 72)\n            pix = page.get_pixmap(matrix=mat)\n\n            # Try to compress to JPEG if PIL is available\n            if HAS_PIL:\n                # Convert pixmap to PIL Image\n                img_data = pix.tobytes(\"png\")\n                img = Image.open(io.BytesIO(img_data))\n\n                # Convert to RGB (JPEG doesn't support alpha channel)\n                if img.mode in ('RGBA', 'LA', 'P'):\n                    rgb_img = Image.new('RGB', img.size, (255, 255, 255))\n                    if img.mode == 'P':\n                        img = img.convert('RGBA')\n                    rgb_img.paste(img, mask=img.split()[-1] if img.mode in ('RGBA', 'LA') else None)\n                    img = rgb_img\n\n                # Save as JPEG with compression\n                buffer = io.BytesIO()\n                img.save(buffer, format='JPEG', quality=85, optimize=True)\n                img_bytes = buffer.getvalue()\n\n                # Encode to base64\n                base64_str = base64.b64encode(img_bytes).decode(\"utf-8\")\n                return f\"data:image/jpeg;base64,{base64_str}\"\n            else:\n                # Fallback to PNG\n                img_bytes = pix.tobytes(\"png\")\n                base64_str = base64.b64encode(img_bytes).decode(\"utf-8\")\n                return f\"data:image/png;base64,{base64_str}\"\n        finally:\n            doc.close()\n\n    def _generate_vscode_link(self, pdf_path: str) -> str:\n        \"\"\"\n        Generate vscode:// link to ground truth JSON file.\n\n        Args:\n            pdf_path: Path to the PDF file\n\n        Returns:\n            vscode:// URL or empty string if ground truth file doesn't exist\n        \"\"\"\n        # Get the stem of the PDF filename\n        pdf_stem = Path(pdf_path).stem\n\n        # Find corresponding ground truth JSON file\n        gt_file = self.ground_truth_dir / f\"{pdf_stem}.json\"\n\n        if gt_file.exists():\n            # Convert to absolute path for VS Code link\n            abs_path = gt_file.resolve()\n            return f\"vscode://file/{abs_path}\"\n\n        return \"\"\n\n    def _get_metric_class(self, score: float) -> str:\n        \"\"\"\n        Get CSS class based on metric score.\n\n        Args:\n            score: Score value between 0 and 1\n\n        Returns:\n            CSS class name: 'good', 'warning', or 'poor'\n        \"\"\"\n        if score >= 0.9:\n            return \"good\"\n        elif score >= 0.7:\n            return \"warning\"\n        else:\n            return \"poor\"\n"
  },
  {
    "path": "docs/src/content/docs/liteparse/_meta.yml",
    "content": "label: LiteParse\norder: 1\ncollapsed: false\n"
  },
  {
    "path": "docs/src/content/docs/liteparse/cli-reference.md",
    "content": "---\ntitle: CLI Reference\ndescription: Complete reference for all LiteParse CLI commands and options.\nsidebar:\n  order: 5\n---\n\nLiteParse provides the `lit` CLI with three commands: `parse`, `batch-parse`, and `screenshot`.\n\n## `lit parse`\n\nParse a single document.\n\n```\nlit parse [options] <file>\n```\n\n### Arguments\n\n| Argument | Description |\n|----------|-------------|\n| `file` | Path to the document file, or `-` to read from stdin |\n\n### Options\n\n| Option | Description | Default |\n|--------|-------------|---------|\n| `-o, --output <file>` | Write output to a file instead of stdout | — |\n| `--format <format>` | Output format: `json` or `text` | `text` |\n| `--ocr-server-url <url>` | HTTP OCR server URL | — (uses Tesseract) |\n| `--no-ocr` | Disable OCR entirely | — |\n| `--ocr-language <lang>` | OCR language code | `en` |\n| `--num-workers <n>` | Pages to OCR in parallel | CPU cores - 1 |\n| `--max-pages <n>` | Maximum pages to parse | `10000` |\n| `--target-pages <pages>` | Pages to parse (e.g., `\"1-5,10\"`) | — (all pages) |\n| `--dpi <dpi>` | Rendering DPI | `150` |\n| `--no-precise-bbox` | **Deprecated:** Disable populating the output boundingBoxes array. Will be removed in v2.0. Text item coordinates (`x`, `y`, `width`, `height`) are always present regardless. | — |\n| `--preserve-small-text` | Keep very small text | — |\n| `--password <password>` | Password for encrypted/protected documents | — |\n| `--config <file>` | JSON config file path | — |\n| `-q, --quiet` | Suppress progress output | — |\n\n### Examples\n\n```bash\n# Basic text parsing\nlit parse report.pdf\n\n# JSON output with bounding boxes\nlit parse report.pdf --format json -o report.json\n\n# Parse pages 1-5 only, no OCR\nlit parse report.pdf --target-pages \"1-5\" --no-ocr\n\n# High-DPI rendering with French OCR\nlit parse report.pdf --dpi 300 --ocr-language fra\n\n# Use an external OCR server\nlit parse report.pdf --ocr-server-url http://localhost:8828/ocr\n\n# Pipe output to another tool\nlit parse report.pdf -q | wc -l\n\n# Parse a remote file via stdin\ncurl -sL https://example.com/report.pdf | lit parse --no-ocr -\n```\n\n---\n\n## `lit batch-parse`\n\nParse multiple documents in a directory.\n\n```\nlit batch-parse [options] <input-dir> <output-dir>\n```\n\n### Arguments\n\n| Argument | Description |\n|----------|-------------|\n| `input-dir` | Directory containing documents to parse |\n| `output-dir` | Directory for output files |\n\n### Options\n\n| Option | Description | Default |\n|--------|-------------|---------|\n| `--format <format>` | Output format: `json` or `text` | `text` |\n| `--ocr-server-url <url>` | HTTP OCR server URL | — (uses Tesseract) |\n| `--no-ocr` | Disable OCR entirely | — |\n| `--ocr-language <lang>` | OCR language code | `en` |\n| `--num-workers <n>` | Pages to OCR in parallel | CPU cores - 1 |\n| `--max-pages <n>` | Maximum pages per file | `10000` |\n| `--dpi <dpi>` | Rendering DPI | `150` |\n| `--no-precise-bbox` | **Deprecated:** Disable populating the output boundingBoxes array. Will be removed in v2.0. Text item coordinates (`x`, `y`, `width`, `height`) are always present regardless. | — |\n| `--recursive` | Search subdirectories | — |\n| `--extension <ext>` | Only process this extension (e.g., `\".pdf\"`) | — (all supported) |\n| `--password <password>` | Password for encrypted/protected documents (applied to all files) | — |\n| `--config <file>` | JSON config file path | — |\n| `-q, --quiet` | Suppress progress output | — |\n\n### Examples\n\n```bash\n# Parse all supported files in a directory\nlit batch-parse ./documents ./output\n\n# Recursively parse only PDFs\nlit batch-parse ./documents ./output --recursive --extension \".pdf\"\n\n# Batch parse with JSON output and no OCR\nlit batch-parse ./documents ./output --format json --no-ocr\n\n# Use a config file for consistent settings\nlit batch-parse ./documents ./output --config liteparse.config.json\n```\n\n---\n\n## `lit screenshot`\n\nGenerate page images from a PDF.\n\n```\nlit screenshot [options] <file>\n```\n\n### Arguments\n\n| Argument | Description |\n|----------|-------------|\n| `file` | Path to the PDF file |\n\n### Options\n\n| Option | Description | Default |\n|--------|-------------|---------|\n| `-o, --output-dir <dir>` | Output directory | `./screenshots` |\n| `--target-pages <pages>` | Pages to screenshot (e.g., `\"1,3,5\"` or `\"1-5\"`) | — (all pages) |\n| `--dpi <dpi>` | Rendering DPI | `150` |\n| `--format <format>` | Image format: `png` or `jpg` | `png` |\n| `--password <password>` | Password for encrypted/protected documents | — |\n| `--config <file>` | JSON config file path | — |\n| `-q, --quiet` | Suppress progress output | — |\n\n### Examples\n\n```bash\n# Screenshot all pages\nlit screenshot document.pdf -o ./pages\n\n# First 5 pages at high DPI\nlit screenshot document.pdf --pages \"1-5\" --dpi 300 -o ./pages\n\n# JPG format for smaller files\nlit screenshot document.pdf --format jpg -o ./pages\n\n# Specific pages only\nlit screenshot document.pdf --pages \"1,5,10\" -o ./pages\n```\n\n---\n\n## Global options\n\nThese options are available on all commands:\n\n| Option | Description |\n|--------|-------------|\n| `-h, --help` | Show help for a command |\n| `-V, --version` | Show version number |\n"
  },
  {
    "path": "docs/src/content/docs/liteparse/getting_started.md",
    "content": "---\ntitle: Getting Started\ndescription: Install LiteParse and parse your first document in under a minute.\nsidebar:\n  order: 1\n---\n\n## Installation\n\nInstall LiteParse globally via npm to use the `lit` command anywhere:\n\n```bash\nnpm i -g @llamaindex/liteparse\n```\n\nFor macOS and Linux users, LiteParse can be also installed via `brew`:\n\n```bash\nbrew tap run-llama/liteparse\nbrew install llamaindex-liteparse\n```\n\n## Quick start\n\nOnce installed, you can start parsing from the command line:\n\n```bash\n# Parse a PDF and print text to stdout\nlit parse document.pdf\n\n# Save output to a file\nlit parse document.pdf -o output.txt\n\n# Get structured JSON with bounding boxes\nlit parse document.pdf --format json -o output.json\n\n# Parse only specific pages\nlit parse document.pdf --target-pages \"1-5,10,15-20\"\n```\n\n### Batch parsing\n\nParse an entire directory of documents at once:\n\n```bash\nlit batch-parse ./pdfs ./outputs\n```\n\n### Screenshots\n\nGenerate page images from a PDF for LLM agents or visual workflows:\n\n```bash\nlit screenshot document.pdf -o ./screenshots\n```\n\n## Next steps\n\n- [Library usage](/liteparse/guides/library-usage/): Use LiteParse programmatically from TypeScript or Python.\n- [OCR configuration](/liteparse/guides/ocr/): Configure Tesseract, use an external OCR server, or bring your own.\n- [Multi-format support](/liteparse/guides/multi-format/): Parse DOCX, XLSX, PPTX, images, and more.\n- [Agent skill](/liteparse/guides/agent-skill/): Add LiteParse as a skill for coding agents.\n- [CLI reference](/liteparse/cli-reference/): Complete command and option reference.\n"
  },
  {
    "path": "docs/src/content/docs/liteparse/guides/_meta.yml",
    "content": "label: Guides\norder: 2\ncollapsed: false\n"
  },
  {
    "path": "docs/src/content/docs/liteparse/guides/agent-skill.md",
    "content": "---\ntitle: Agent Skill\ndescription: Add LiteParse as a skill for coding agents like Claude Code, Cursor, and others.\nsidebar:\n  order: 6\n---\n\nLiteParse can be installed as a **coding agent skill** using Vercel's [skills](https://github.com/vercel-labs/skills) utility. This gives your coding agent the ability to process documents, generate screenshots, and parse text from files, all locally.\n\n## Installation\n\nAdd the LiteParse skill to your project:\n\n```bash\nnpx skills add run-llama/llamaparse-agent-skills --skill liteparse\n```\n\nThis downloads a skill file that compatible coding agents (Claude Code, Cursor, etc.) will automatically pick up.\n\nOnce configured, your agent will be able to call the LiteParse CLI commands directly from its code execution environment. This means you can have your agent parse PDFs, pull out the text, and generate screenshots on the fly as part of its reasoning process.\n\n## Example prompts\n\nOnce the skill is installed, you can ask your coding agent things like:\n\n- \"Parse this PDF and extract the text as JSON\"\n- \"Extract text from all the DOCX files in the `./contracts` folder\"\n- \"Screenshot pages 1-5 of this PDF at 300 DPI\"\n- \"Parse this scanned document using the PaddleOCR server on localhost:8828\"\n- \"Get the bounding boxes for all text on page 3\"\n\n\n## Configuring Defaults\n\nYou might want to configure some defaults so that your agent doesn't have to specify them in every prompt. You can create a `liteparse.config.json` file in the root of your project with settings like:\n\n```json\n{\n  \"ocrLanguage\": \"en\",\n  \"ocrEnabled\": true,\n  \"maxPages\": 1000,\n  \"dpi\": 150,\n  \"outputFormat\": \"json\",\n  \"preserveVerySmallText\": false\n}\n```\n\nThis is especially useful for custom OCR servers. Just add the `ocrServerUrl` to your config:\n\n```json\n{\n  \"ocrServerUrl\": \"http://localhost:8828/ocr\",\n  \"ocrLanguage\": \"en\",\n  \"outputFormat\": \"json\"\n}\n```\n"
  },
  {
    "path": "docs/src/content/docs/liteparse/guides/library-usage.md",
    "content": "---\ntitle: Library Usage\ndescription: Use LiteParse programmatically from TypeScript or Python.\nsidebar:\n  order: 1\n---\n\nLiteParse can be used as a library in your own code, not just from the CLI. There are packages for both TypeScript and Python.\n\n## TypeScript\n\nInstall as a project dependency:\n\n```bash\nnpm install @llamaindex/liteparse\n# or\npnpm add @llamaindex/liteparse\n```\n\n### Parsing a document\n\n```typescript\nimport { LiteParse } from \"@llamaindex/liteparse\";\n\nconst parser = new LiteParse({ ocrEnabled: true });\nconst result = await parser.parse(\"document.pdf\");\n\n// Full document text with layout preserved\nconsole.log(result.text);\n\n// Per-page data\nfor (const page of result.pages) {\n  console.log(`Page ${page.pageNum}: ${page.textItems.length} text items`);\n}\n```\n\n### JSON output with bounding boxes\n\n```typescript\nconst parser = new LiteParse({ outputFormat: \"json\" });\nconst result = await parser.parse(\"document.pdf\");\n\nfor (const page of result.json?.pages || []) {\n  for (const item of page.textItems) {\n    console.log(`[${item.x}, ${item.y}] → [${item.x + item.width}, ${item.y + item.height}] ${item.text}`);\n  }\n}\n```\n\n### Configuration\n\nPass any config options to the constructor. You only need to specify what you want to override:\n\n```typescript\nconst parser = new LiteParse({\n  ocrEnabled: true,\n  ocrServerUrl: \"http://localhost:8828/ocr\",\n  ocrLanguage: \"fra\",\n  dpi: 300,\n  outputFormat: \"json\",\n  targetPages: \"1-10\",\n  password: \"secret\",        // for encrypted/protected documents\n});\n```\n\n### Buffer / Uint8Array input\n\nYou can pass raw bytes directly instead of a file path. PDF buffers are parsed with **zero disk I/O** — no temp files are written:\n\n```typescript\nimport { readFile } from \"fs/promises\";\n\nconst parser = new LiteParse();\n\n// From a file read\nconst pdfBytes = await readFile(\"document.pdf\");\nconst result = await parser.parse(pdfBytes);\n\n// From an HTTP response\nconst response = await fetch(\"https://example.com/document.pdf\");\nconst buffer = Buffer.from(await response.arrayBuffer());\nconst result2 = await parser.parse(buffer);\n```\n\nNon-PDF buffers (images, Office documents) are written to a temp directory for format conversion. You can control the temp directory with the `LITEPARSE_TMPDIR` environment variable.\n\n### Screenshots\n\nGenerate page images as buffers — useful for sending to LLMs or saving to disk. Accepts file paths, `Buffer`, or `Uint8Array`:\n\n```typescript\nconst parser = new LiteParse();\nconst screenshots = await parser.screenshot(\"document.pdf\");\n\nfor (const shot of screenshots) {\n  console.log(`Page ${shot.pageNum}: ${shot.width}x${shot.height}`);\n  // shot.imageBuffer contains the raw PNG/JPG data\n}\n\n// Also works with buffer input\nconst pdfBytes = await readFile(\"document.pdf\");\nconst shots = await parser.screenshot(pdfBytes, [1, 2, 3]);\n```\n\n### Environment variables\n\n| Variable | Description |\n|----------|-------------|\n| `TESSDATA_PREFIX` | Path to a directory containing Tesseract `.traineddata` files. For offline/air-gapped environments. Also available as the `tessdataPath` config option. |\n| `LITEPARSE_TMPDIR` | Override the temp directory for format conversion. Defaults to `os.tmpdir()`. |\n\nSee the [API reference](/liteparse/api/) for full type details.\n\n---\n\n## Python\n\nThe Python package is a wrapper around the LiteParse Node.js CLI. **Node.js (>= 18) must be installed** on your system.\n\n### Installation\n\nFirst, install the LiteParse CLI:\n\n```bash\nnpm install -g @llamaindex/liteparse\n```\n\nThen install the Python package:\n\n```bash\npip install liteparse\n```\n\n<Aside type=\"caution\">\n  The Python package calls the LiteParse CLI under the hood via subprocess. Node.js (>= 18) is required. While the package can auto-install the CLI via `npm install -g @llamaindex/liteparse` on first use, it is recommended to install it separately beforehand.\n</Aside>\n\n### Parsing a document\n\n```python\nfrom liteparse import LiteParse\n\nparser = LiteParse()\nresult = parser.parse(\"document.pdf\")\n\n# Full document text\nprint(result.text)\n\n# Per-page data\nfor page in result.pages:\n    print(f\"Page {page.pageNum}: {len(page.textItems)} text items\")\n```\n\n### Configuration\n\nThe `LiteParse` constructor accepts `cli_path` (to override CLI auto-detection) and `install_if_not_available` (to control auto-install behavior). All parsing options are passed per-call:\n\n```python\nparser = LiteParse()\n\nresult = parser.parse(\n    \"document.pdf\",\n    ocr_enabled=True,\n    ocr_server_url=\"http://localhost:8828/ocr\",\n    ocr_language=\"fra\",\n    dpi=300,\n    target_pages=\"1-5\",\n    password=\"secret\",  # for encrypted/protected documents\n)\n```\n\n### Parsing from bytes\n\nIf you already have file contents in memory (e.g. from a web upload), pass them directly to `parse()`:\n\n```python\nwith open(\"document.pdf\", \"rb\") as f:\n    pdf_bytes = f.read()\n\nresult = parser.parse(pdf_bytes)\nprint(result.text)\n```\n\n### Batch parsing\n\nFor multiple files, batch mode reuses the PDF engine and is significantly faster:\n\n```python\nresult = parser.batch_parse(\n    input_dir=\"./documents\",\n    output_dir=\"./output\",\n    recursive=True,\n    extension_filter=\".pdf\",\n)\n\nprint(f\"Output written to: {result.output_dir}\")\n```\n"
  },
  {
    "path": "docs/src/content/docs/liteparse/guides/multi-format.md",
    "content": "---\ntitle: Multi-Format Support\ndescription: Parse Word documents, spreadsheets, presentations, and images with LiteParse.\nsidebar:\n  order: 3\n---\n\nLiteParse automatically converts non-PDF formats to PDF before parsing. This lets you use the same parsing pipeline for Office documents, images, and more.\n\n## Supported formats\n\n### Office documents (via LibreOffice)\n\n| Category | Extensions |\n|----------|-----------|\n| Word | `.doc`, `.docx`, `.docm`, `.odt`, `.rtf` |\n| PowerPoint | `.ppt`, `.pptx`, `.pptm`, `.odp` |\n| Spreadsheets | `.xls`, `.xlsx`, `.xlsm`, `.ods`, `.csv`, `.tsv` |\n\n### Images (via ImageMagick)\n\n`.jpg`, `.jpeg`, `.png`, `.gif`, `.bmp`, `.tiff`, `.webp`, `.svg`\n\nImages are converted to PDF and then parsed with OCR to extract text.\n\n## Installing dependencies\n\nFormat conversion uses standard system tools. Install the ones you need:\n\n### LibreOffice (for Office documents)\n\n```bash\n# macOS\nbrew install --cask libreoffice\n\n# Ubuntu/Debian\napt-get install libreoffice\n\n# Windows\nchoco install libreoffice-fresh\n```\n\n> On Windows, you may need to add the LibreOffice CLI directory (typically `C:\\Program Files\\LibreOffice\\program`) to your PATH and restart.\n\n### ImageMagick (for images)\n\n```bash\n# macOS\nbrew install imagemagick\n\n# Ubuntu/Debian\napt-get install imagemagick\n\n# Windows\nchoco install imagemagick.app\n```\n\n## Usage\n\nOnce the dependencies are installed, just pass any supported file to `lit parse`:\n\n```bash\nlit parse report.docx\nlit parse slides.pptx --format json\nlit parse spreadsheet.xlsx -o output.txt\nlit parse scan.png\n```\n\nBatch mode also handles mixed formats:\n\n```bash\nlit batch-parse ./documents ./output --recursive\n```\n\n## How it works\n\n1. LiteParse detects the file extension\n2. If it's not a PDF, it converts to PDF using the appropriate tool (LibreOffice or ImageMagick)\n3. The resulting PDF is parsed normally\n4. Temporary conversion files are cleaned up automatically\n\nIf the required conversion tool isn't installed, LiteParse will return an error explaining which dependency is needed.\n"
  },
  {
    "path": "docs/src/content/docs/liteparse/guides/ocr.md",
    "content": "---\ntitle: OCR Configuration\ndescription: Configure OCR in LiteParse — built-in Tesseract, or bring your own via HTTP servers.\nsidebar:\n  order: 2\n---\n\nLiteParse uses OCR selectively — only on embedded images or pages where native text extraction didn't find text. This keeps parsing fast while still capturing text from scanned pages and embedded images.\n\n## Built-in Tesseract (default)\n\nTesseract.js is bundled with LiteParse. The only setup is the automatic download of the Tesseract model files on first use. Just run:\n\n```bash\nlit parse document.pdf\n```\n\nIf bundling LiteParse into a docker container or server environment, you might want to pre-download the Tesseract files to avoid network calls at runtime with the above command or similar.\n\n### Language support\n\nSpecify the OCR language for better accuracy on non-English documents:\n\n```bash\nlit parse document.pdf --ocr-language fra    # French\nlit parse document.pdf --ocr-language deu    # German\nlit parse document.pdf --ocr-language jpn    # Japanese\n```\n\nTesseract uses [ISO 639-3](https://tesseract-ocr.github.io/tessdoc/Data-Files-in-different-versions.html) language codes (`eng`, `fra`, `deu`, etc.).\n\n### Disabling OCR\n\nIf you don't need OCR (pure native-text PDFs, or you don't care about images), disable it for faster parsing:\n\n```bash\nlit parse document.pdf --no-ocr\n```\n\n## HTTP OCR servers\n\nFor higher accuracy or GPU-accelerated OCR, you can point LiteParse at an HTTP OCR server. LiteParse ships with ready-to-use examples for popular OCR engines.\n\n### EasyOCR\n\n```bash\n# Start the EasyOCR server (requires Python)\ngit clone https://github.com/run-llama/liteparse.git\ncd liteparse/ocr/easyocr\npip install -r requirements.txt\npython server.py\n\n# Parse with EasyOCR in another terminal\nlit parse document.pdf --ocr-server-url http://localhost:8828/ocr\n```\n\n### PaddleOCR\n\n```bash\n# Start the PaddleOCR server (requires Python)\ngit clone https://github.com/run-llama/liteparse.git\ncd liteparse/ocr/paddleocr\npip install -r requirements.txt\npython server.py\n\n# Parse with PaddleOCR in another terminal\nlit parse document.pdf --ocr-server-url http://localhost:8828/ocr\n```\n\n### Parallel OCR workers\n\nLiteParse OCRs multiple pages in parallel. By default, it uses one fewer worker than your CPU core count. Override this with:\n\n```bash\nlit parse document.pdf --num-workers 8\n```\n\nThis is useful if you need to slow down OCR requests to an external server or if your OCR engine is GPU-accelerated and can handle more concurrency.\n\n## Custom OCR servers\n\nYou can integrate any OCR engine by implementing the LiteParse OCR API. Your server needs a single endpoint:\n\n```\nPOST /ocr\nContent-Type: multipart/form-data\n```\n\n**Request fields:**\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `file` | binary | Yes | Image file (PNG, JPG, etc.) |\n| `language` | string | No | ISO 639-1 language code (default: `en`) |\n\n**Response format:**\n\n```json\n{\n  \"results\": [\n    {\n      \"text\": \"recognized text\",\n      \"bbox\": [x1, y1, x2, y2],\n      \"confidence\": 0.95\n    }\n  ]\n}\n```\n\nEach result contains:\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `text` | string | Recognized text |\n| `bbox` | `[x1, y1, x2, y2]` | Bounding box in pixels. Origin is top-left, x goes right, y goes down |\n| `confidence` | number | Score from 0.0 to 1.0 |\n\n### Testing your server\n\n```bash\n# Quick test with curl\ncurl -X POST http://localhost:8080/ocr \\\n  -F \"file=@test.png\" \\\n  -F \"language=en\" | jq .\n\n# Use with LiteParse\nlit parse document.pdf --ocr-server-url http://localhost:8080/ocr\n```\n\n### Common Gotchas\n\n- Return `{\"results\": []}` if no text is detected\n- Bounding boxes must be axis-aligned (`[x1, y1, x2, y2]` where top-left to bottom-right)\n- If your engine returns rotated boxes, convert to axis-aligned by taking min/max coordinates\n- If your engine doesn't provide confidence scores, return `1.0`\n- Results should be in reading order (top-to-bottom, left-to-right)\n- Cache OCR models in memory rather than reloading per request\n\n### A note on OCR approaches\n\nThese days, its common to apply the term \"OCR\" to both traditional approaches and newer LLM-based document understanding models. \n\nThe LiteParse OCR API is designed specifically for approaches that return text with bounding boxes. \n\nIf you are trying to integrate a method that doesn't return bounding boxes, you will have to generate dummy bounding boxes.\n"
  },
  {
    "path": "docs/src/content/docs/liteparse/guides/parsing-urls.md",
    "content": "---\ntitle: Parsing URLs\ndescription: Parse remote documents by reading URLs.\nsidebar:\n  order: 5\n---\n\nTo parse remote files, LiteParse support both CLI and library usage for reading bytes and streams. This means the CLI can download them with any tool you like and pipe the bytes to `lit parse` using `-` as the file argument, while the libraries can fetch the bytes directly from the URL and pass them to the parser.\n\n## CLI usage\n\n```bash\n# Parse a remote PDF\ncurl -sL https://example.com/report.pdf | lit parse -\n\n# With options\ncurl -sL https://example.com/report.pdf | lit parse --no-ocr --format json -\n\n# Save to a file\ncurl -sL https://example.com/report.pdf | lit parse -o report.txt -\n```\n\nThe `-` argument tells LiteParse to read from stdin instead of a file path. Any tool that writes to stdout works — `curl`, `wget`, `aws s3 cp - -`, etc.\n\n## Library usage\n\nThe TypeScript library accepts `Buffer`/`Uint8Array` directly, so you can handle the download however you like:\n\n```typescript\nimport { LiteParse } from \"@llamaindex/liteparse\";\n\nconst response = await fetch(\"https://example.com/report.pdf\");\nconst buffer = Buffer.from(await response.arrayBuffer());\n\nconst parser = new LiteParse({ ocrEnabled: false });\nconst result = await parser.parse(buffer);\nconsole.log(result.text);\n```\n"
  },
  {
    "path": "docs/src/content/docs/liteparse/guides/visual-citations.md",
    "content": "---\ntitle: Visual Citations with Bounding Boxes\ndescription: Use bounding boxes and screenshots to show exactly where information was found in a document.\nsidebar:\n  order: 4\n---\n\nWhen building agents or RAG workflows, it is often not enough to parse text and call it done. Frequently, users and applications will require you to show _where_ that text came from. \n\nLiteParse gives you spatial coordinates for every text item, plus page screenshots, so you can highlight exact regions on the rendered page.\n\n## How bounding boxes work\n\nWhen you parse a document with JSON output, each page includes a key data source for visual citations: **`textItems`**. Every extracted text element with its position (`x`, `y`, `width`, `height`) and content.\n\n```json\n$ lit parse document.pdf --format json\n{\n  \"pages\": [{\n    \"page\": 1,\n    \"width\": 612,\n    \"height\": 792,\n    \"text\": \"...\",\n    \"textItems\": [\n      { \"text\": \"Revenue grew 15%\", \"x\": 72, \"y\": 200, \"width\": 150, \"height\": 12, ... }\n    ],\n  }]\n}\n```\n\nCoordinates are in **PDF points** (1 point = 1/72 inch). Origin is the top-left corner of the page, with X increasing right and Y increasing down.\n\n## Library usage\n\nThe library lets you do both in a single script, parse for bboxes and generate screenshots. For example, you might be looking for specific information like \"Revenue\" and want to show exactly where it appears on the page:\n\n```typescript\nimport { LiteParse } from \"@llamaindex/liteparse\";\n\nconst parser = new LiteParse({ outputFormat: \"json\", dpi: 150 });\n\nconst result = await parser.parse(\"report.pdf\");\nconst screenshots = await parser.screenshot(\"report.pdf\");\n\n// Find a text item by its content\nfor (const page of result.json?.pages || []) {\n  for (const item of page.textItems) {\n    if (item.text.includes(\"Revenue\")) {\n      console.log(`Found on page ${page.page}: (${item.x}, ${item.y}) ${item.width}×${item.height}`);\n    }\n  }\n}\n```\n\n## Converting coordinates to image pixels\n\nText item coordinates are in PDF points, but screenshots are in pixels. To draw highlights on a screenshot, you need to scale the coordinates:\n\n```typescript\nconst scaleFactor = dpi / 72; // PDF points → pixels at your chosen DPI\n\nfunction itemToPixels(item, dpi = 150) {\n  const scale = dpi / 72;\n  return {\n    x: item.x * scale,\n    y: item.y * scale,\n    width: item.width * scale,\n    height: item.height * scale,\n  };\n}\n```\n\nFor example, at the default 150 DPI the scale factor is `150 / 72 ≈ 2.08`, so a text item at `(72, 200)` maps to pixel `(150, 416)`.\n\n## Searching for phrases with `searchItems`\n\nA single text item often contains just one word or fragment. A phrase like `\"0°C to 70°C\"` may span several adjacent items. The `searchItems` utility handles this — it concatenates consecutive items, finds matches, and returns merged text items with combined bounding boxes:\n\n```typescript\nimport { LiteParse, searchItems } from \"@llamaindex/liteparse\";\n\nconst parser = new LiteParse({ outputFormat: \"json\" });\nconst result = await parser.parse(\"report.pdf\");\n\nfor (const page of result.json.pages) {\n  const matches = searchItems(page.textItems, { phrase: \"0°C to 70°C\" });\n  for (const match of matches) {\n    console.log(`Found \"${match.text}\" at (${match.x}, ${match.y}) ${match.width}×${match.height}`);\n  }\n}\n```\n\nEach returned item has the same shape as a regular text item, with merged coordinates spanning all the items that contributed to the match.\n\nFor single-word searches, iterating `textItems` individually (as shown in the library usage section above) is simpler and works fine.\n\n## Full example: highlighting citations with sharp\n\nHere's a complete workflow that parses a PDF, searches for a phrase, and draws yellow highlight boxes on the page screenshot:\n\n```typescript\nimport { LiteParse, searchItems } from \"@llamaindex/liteparse\";\nimport sharp from \"sharp\";\n\nconst DPI = 150;\nconst SCALE = DPI / 72;\n\nasync function main() {\n  const parser = new LiteParse({ outputFormat: \"json\", dpi: DPI });\n\n  const result = await parser.parse(\"manual.pdf\");\n  const screenshots = await parser.screenshot(\"manual.pdf\");\n\n  // Search for a phrase, grouped by page\n  const query = \"0°C to 70°C\";\n  const hitsByPage = new Map<number, Array<{ x: number; y: number; width: number; height: number }>>();\n\n  for (const page of result.json?.pages || []) {\n    const matches = searchItems(page.textItems, { phrase: query });\n    if (matches.length) hitsByPage.set(page.page, matches);\n  }\n\n  // Draw all highlights per page into a single image\n  for (const [pageNum, rects] of hitsByPage) {\n    const shot = screenshots.find((s) => s.pageNum === pageNum);\n    if (!shot) continue;\n\n    const composites = await Promise.all(\n      rects.map(async (rect) => {\n        const pixel = {\n          left: Math.round(rect.x * SCALE),\n          top: Math.round(rect.y * SCALE),\n          width: Math.round(rect.width * SCALE),\n          height: Math.round(rect.height * SCALE),\n        };\n\n        const overlay = await sharp({\n          create: {\n            width: pixel.width,\n            height: pixel.height,\n            channels: 4,\n            background: { r: 255, g: 255, b: 0, alpha: 0.3 },\n          },\n        })\n          .png()\n          .toBuffer();\n\n        return { input: overlay, left: pixel.left, top: pixel.top };\n      })\n    );\n\n    const highlighted = await sharp(shot.imageBuffer)\n      .composite(composites)\n      .png()\n      .toBuffer();\n\n    await sharp(highlighted).toFile(`citation_page${pageNum}.png`);\n    console.log(`Saved citation_page${pageNum}.png (${rects.length} highlights)`);\n  }\n}\n\nmain().catch(console.error);\n```\n\nRunning this script on a PDF will produce new images with the search phrase highlighted, showing exactly where the information was found on the page.\n\n![Example output showing highlighted search results on a PDF page](visual_citation.png)\n\n## CLI usage\n\nParse to JSON to get bounding boxes:\n\n```bash\nlit parse document.pdf --format json -o result.json\n```\n\nGenerate page screenshots alongside:\n\n```bash\nlit screenshot document.pdf -o ./screenshots\n```\n\nFrom there, you (or an agent) can process the resulting JSON and screenshots as needed using any tools available.\n\n## Deprecated: `boundingBoxes`\n\nThe `boundingBoxes` array in JSON output is **deprecated** and will be removed in **v2.0**. It is a redundant representation of the same spatial data already available on each text item (`x`, `y`, `width`, `height`). Use `textItems` directly instead — it has the same coordinates plus text content, font metadata, and consistent indexing.\n\n## Tips\n\n- Use the same `dpi` value for both `parse()` and `screenshot()`. The default is `150` for both.\n- Page `width` and `height` in the JSON are in PDF points, matching the coordinate space. Use these if you need to normalize coordinates to percentages.\n"
  },
  {
    "path": "docs/src/content/docs/liteparse/index.md",
    "content": "---\ntitle: What is LiteParse?\ndescription: Fast, local PDF parsing with spatial text parsing, OCR, and bounding boxes.\nsidebar:\n  order: 0\n---\n\nLiteParse is an open-source document parsing library that parses text with spatial layout information and bounding boxes. It runs entirely on your machine, with no cloud dependencies, no LLMs, no API keys.\n\nLiteParse is designed specifically for use cases that require fast, accurate text parsing: real-time applications, coding agents, and local workflows. It provides a simple CLI and library API for parsing PDFs, Office documents, and images, with built-in OCR support.\n\n## What can LiteParse do?\n\n- **Parse PDFs** with precise spatial layout. Text comes back positioned where it appears on the page\n- **Extract bounding boxes** for every text line, ready for downstream processing or visualization\n- **OCR scanned documents** using built-in Tesseract.js or plug in your own OCR server\n- **Parse Office files and images** with support for DOCX, XLSX, PPTX, PNG, JPG, and more via automatic conversion\n- **Screenshot PDF pages** as high-quality images for LLM-based workflows\n- **Use from TypeScript, Python, or the CLI** — whatever fits your stack\n\n## Get started\n\n- [Getting started](/liteparse/getting_started/): Install LiteParse and parse your first document.\n- [Library usage](/liteparse/guides/library-usage/): Use LiteParse from TypeScript or Python code.\n- [CLI reference](/liteparse/cli-reference/): Complete command and option reference.\n- [API reference](/liteparse/api/): TypeScript library types and methods.\n"
  },
  {
    "path": "docs.config.mjs",
    "content": "export default {\n  section: \"liteparse\",\n  label: \"LiteParse\",\n  content: [\n    { src: \"./docs/src/content/docs/liteparse\", dest: \"liteparse\" },\n  ],\n  sidebar: [{\n    label: \"LiteParse\",\n    content: { type: \"autogenerate\", directory: \"liteparse\", collapsed: true },\n  }],\n};\n"
  },
  {
    "path": "eslint.config.js",
    "content": "import eslint from \"@eslint/js\";\nimport tseslint from \"typescript-eslint\";\nimport eslintConfigPrettier from \"eslint-config-prettier\";\n\nexport default tseslint.config(\n  eslint.configs.recommended,\n  ...tseslint.configs.recommended,\n  eslintConfigPrettier,\n  {\n    languageOptions: {\n      parserOptions: {\n        projectService: true,\n        tsconfigRootDir: import.meta.dirname,\n      },\n    },\n  },\n  {\n    ignores: [\"dist/**\", \"node_modules/**\", \"src/vendor/**\", \"examples/**\"],\n  },\n  {\n    rules: {\n      // Allow unused vars that start with underscore\n      \"@typescript-eslint/no-unused-vars\": [\n        \"error\",\n        {\n          argsIgnorePattern: \"^_\",\n          varsIgnorePattern: \"^_\",\n        },\n      ],\n      // Allow explicit any in some cases (can be tightened later)\n      \"@typescript-eslint/no-explicit-any\": \"warn\",\n    },\n  }\n);\n"
  },
  {
    "path": "ocr/README.md",
    "content": "# ocr/\n\nExample OCR server implementations that conform to the LiteParse OCR API specification.\n\nThese servers allow you to use alternative OCR engines instead of the built-in Tesseract.js.\n\n## Why Use an External OCR Server?\n\n| Feature | Tesseract.js (built-in) | EasyOCR | PaddleOCR |\n|---------|-------------------------|---------|-----------|\n| Setup | Zero (included) | uv | uv |\n| Speed | Moderate | Moderate | Fast (2-3x) |\n| Accuracy (Latin) | Good | Good | Good |\n| Accuracy (CJK) | Fair | Good | Excellent |\n| Languages | 100+ | 80+ | 80+ |\n| Memory | In-process | Separate | Separate |\n\n**Recommendations:**\n- **Quick start**: Use built-in Tesseract (no setup)\n- **Asian languages**: Use PaddleOCR (best CJK support)\n- **General use**: EasyOCR (good balance)\n\n## Available Servers\n\n### [easyocr/](./easyocr/)\nFlask server wrapping EasyOCR library.\n- Port: **8828**\n- Good general-purpose OCR\n- 80+ languages\n\n### [paddleocr/](./paddleocr/)\nFlask server wrapping PaddleOCR library.\n- Port: **8829**\n- Excellent for Chinese, Japanese, Korean\n- 2-3x faster than EasyOCR\n\n## Quick Start\n\n```bash\n# Start EasyOCR server\ncd ocr/easyocr\nuv run server.py\n\n# OR start PaddleOCR server\ncd ocr/paddleocr\nuv run server.py\n```\n\nThen use with LiteParse:\n\n```bash\n# CLI\nlit parse document.pdf --ocr-server-url http://localhost:8828/ocr\n\n# Code\nconst parser = new LiteParse({\n  ocrServerUrl: 'http://localhost:8828/ocr',\n  ocrLanguage: 'en',\n});\n```\n\n## API Specification\n\nAll servers implement the same API (defined in `OCR_API_SPEC.md`):\n\n**Endpoint:** `POST /ocr`\n\n**Request:**\n- Content-Type: `multipart/form-data`\n- Fields:\n  - `file` - Image file\n  - `language` - Language code (e.g., 'en', 'zh', 'ja')\n\n**Response:**\n```json\n{\n  \"results\": [\n    {\n      \"text\": \"recognized text\",\n      \"bbox\": [x1, y1, x2, y2],\n      \"confidence\": 0.95\n    }\n  ]\n}\n```\n\n## Creating a Custom OCR Server\n\nTo implement your own OCR server:\n\n1. Create a Flask/FastAPI/Express server\n2. Accept `POST /ocr` with multipart form data\n3. Return JSON with `results` array containing:\n   - `text` - Recognized text string\n   - `bbox` - Bounding box as `[x1, y1, x2, y2]`\n   - `confidence` - Confidence score (0-1)\n\n4. (Optional) Implement `GET /health` endpoint\n\nSee the existing servers as reference implementations.\n\n## Language Codes\n\nMost servers accept ISO 639-1 codes (e.g., 'en', 'zh', 'ja') and map them internally:\n\n| ISO Code | Language | Notes |\n|----------|----------|-------|\n| en | English | |\n| zh | Chinese (Simplified) | |\n| zh-tw | Chinese (Traditional) | |\n| ja | Japanese | |\n| ko | Korean | |\n| fr | French | |\n| de | German | |\n| es | Spanish | |\n| ar | Arabic | |\n| hi | Hindi | |\n"
  },
  {
    "path": "ocr/easyocr/Dockerfile",
    "content": "FROM ghcr.io/astral-sh/uv:python3.12-trixie\n\n# Install system dependencies\nRUN apt-get update && apt-get install -y \\\n    libgomp1 \\\n    libglib2.0-0 \\\n    libsm6 \\\n    libxext6 \\\n    libxrender-dev \\\n    libgl1 \\\n    && rm -rf /var/lib/apt/lists/*\n\n# Set working directory\nWORKDIR /app\n\n# Copy pyproject.toml and server code\nCOPY ./*py* .\n\n# install necessary dependencies\nRUN uv sync\n\n# Expose port\nEXPOSE 8828\n\n# Run server\nCMD [\"uv\", \"run\", \"python3\", \"server.py\"]\n"
  },
  {
    "path": "ocr/easyocr/README.md",
    "content": "# EasyOCR Service\n\nThis is a simple Flask server that wraps EasyOCR to conform to the LiteParse OCR API specification (see `../../OCR_API_SPEC.md`).\n\n## Build and Run\n\n```bash\n# install and run (in one command)\nuv run server.py\n```\n\n## Usage\n\nThe service exposes a single endpoint:\n\n- `POST /ocr` - Perform OCR on an uploaded image\n\n### Parameters\n\n- `file` - Image file (multipart/form-data)\n- `language` - Language code (e.g., 'en', 'fr', 'de')\n\n### Example\n\n```bash\ncurl -X POST -F \"file=@image.png\" -F \"language=en\" http://localhost:8828/ocr\n```\n\n### Response Format\n\n```json\n{\n  \"results\": [\n    {\n      \"text\": \"recognized text\",\n      \"bbox\": [x1, y1, x2, y2],\n      \"confidence\": 0.95\n    }\n  ]\n}\n```\n\nThis conforms to the LiteParse OCR API specification.\n\n## Supported Languages\n\nEasyOCR supports 80+ languages. Common language codes:\n\n- `en` - English\n- `fr` - French\n- `de` - German\n- `es` - Spanish\n- `zh` - Chinese\n- `ja` - Japanese\n- `ko` - Korean\n- `ar` - Arabic\n\nFull list: https://www.jaided.ai/easyocr/\n\n## Use with LiteParse\n\nOnce the server is running, use it with LiteParse OSS:\n\n```bash\n# Parse with EasyOCR\nlit parse document.pdf --ocr-server-url http://localhost:8828/ocr\n\n# With specific language\nlit parse document.pdf --ocr-server-url http://localhost:8828/ocr --ocr-language zh\n```\n\nOr in code:\n\n```typescript\nimport { LiteParse } from 'liteparse';\n\nconst parser = new LiteParse({\n  ocrServerUrl: 'http://localhost:8828/ocr',\n  ocrLanguage: 'en',\n});\n\nconst result = await parser.parse('document.pdf');\n```\n\n## Testing\n\nIf you make changes to the server, make sure to adapt and run tests:\n\n```bash\nuv run pytest test_server.py\n```\n"
  },
  {
    "path": "ocr/easyocr/pyproject.toml",
    "content": "[project]\nname = \"easyocr-liteparse\"\nversion = \"0.1.0\"\ndescription = \"Add your description here\"\nreadme = \"README.md\"\nrequires-python = \">=3.12\"\ndependencies = [\n    \"easyocr>=1.7.2\",\n    \"fastapi>=0.132.0\",\n    \"numpy>=2.4.2\",\n    \"pillow>=12.1.1\",\n    \"python-multipart>=0.0.22\",\n    \"uvicorn>=0.41.0\",\n]\n\n[dependency-groups]\ndev = [\n    \"httpx>=0.28.1\",\n    \"pytest>=9.0.2\",\n]\n"
  },
  {
    "path": "ocr/easyocr/server.py",
    "content": "import io\nimport logging\nfrom typing import Any\n\nimport easyocr\nimport numpy as np\nimport uvicorn\nfrom fastapi import FastAPI\nfrom fastapi.datastructures import UploadFile\nfrom fastapi.param_functions import File, Form\nfrom PIL import Image\nfrom pydantic import BaseModel\n\n\nclass OcrResponse(BaseModel):\n    results: list[Any]\n\n\nclass StatusResponse(BaseModel):\n    status: str\n\n\nclass EasyOCRServer:\n    def __init__(self) -> None:\n        self.reader: easyocr.Reader | None = None\n        self.current_language: str | None = None\n\n    def _create_ocr_server(self) -> FastAPI:\n        app = FastAPI()\n\n        @app.post(\"/ocr\")\n        async def ocr_endpoint(\n            file: UploadFile = File(...), language: str = Form(default=\"en\")\n        ) -> OcrResponse:\n            print(\n                f\"Language: {language}. Received file {file.filename or 'no name'} with size {file.size or 'unknown size'} and type {file.content_type or 'unknown type'}\",\n                flush=True,\n            )\n            # Get language from request\n            language = language.lower()\n            if self.reader is None or self.current_language != language:\n                print(f\"Initializing EasyOCR reader for language: {language}\")\n                self.reader = easyocr.Reader([language], gpu=False)\n                self.current_language = language\n\n            image_data = await file.read()\n            image = Image.open(io.BytesIO(image_data))\n\n            # Convert to numpy array\n            image_array = np.array(image)\n\n            # Run OCR\n            results = self.reader.readtext(image_array)  # type: ignore\n\n            # Format results according to LiteParse OCR API spec\n            # Convert from EasyOCR format: [[[x1,y1], [x2,y2], [x3,y3], [x4,y4]], text, confidence]\n            # To standard format: { text, bbox: [x1, y1, x2, y2], confidence }\n            formatted = []\n            for coords, text, confidence in results:\n                # Convert polygon to axis-aligned bounding box\n                # coords is [[x1,y1], [x2,y2], [x3,y3], [x4,y4]]\n                if isinstance(coords, np.ndarray):\n                    coords = coords.tolist()\n\n                # int casting is necessary for pydantic serialization (np.Int32 are not serializable)\n                xs = [int(point[0]) for point in coords]\n                ys = [int(point[1]) for point in coords]\n                bbox = [min(xs), min(ys), max(xs), max(ys)]\n\n                formatted.append(\n                    {\"text\": text, \"bbox\": bbox, \"confidence\": float(confidence)}\n                )\n            return OcrResponse(results=formatted)\n\n        @app.get(\"/health\")\n        def health() -> StatusResponse:\n            return StatusResponse(status=\"healthy\")\n\n        return app\n\n    def serve(self) -> None:\n        app = self._create_ocr_server()\n        uvicorn.run(app, host=\"0.0.0.0\", port=8828)\n\n\nif __name__ == \"__main__\":\n    logging.basicConfig(\n        level=logging.DEBUG,\n    )\n    logging.info(\"Starting server on port 8828\")\n    server = EasyOCRServer()\n    server.serve()\n"
  },
  {
    "path": "ocr/easyocr/test_server.py",
    "content": "import io\nfrom typing import Any\n\nimport pytest\nfrom fastapi.testclient import TestClient\nfrom PIL import Image\n\nfrom server import EasyOCRServer\n\n\n@pytest.fixture(scope=\"module\")\ndef server() -> EasyOCRServer:\n    return EasyOCRServer()\n\n\nclass MockEasyOCRReader:\n    def __init__(self, *args, **kwargs) -> None:\n        self.results = [\n            ([[10, 20], [200, 40]], \"Hello World\", 0.98),\n            ([[10, 50], [250, 70]], \"Total: $42.00\", 0.95),\n            ([[10, 80], [180, 100]], \"Thank you!\", 0.87),\n        ]\n        self.transformed_results = [\n            {\"text\": \"Hello World\", \"bbox\": [10, 20, 200, 40], \"confidence\": 0.98},\n            {\"text\": \"Total: $42.00\", \"bbox\": [10, 50, 250, 70], \"confidence\": 0.95},\n            {\"text\": \"Thank you!\", \"bbox\": [10, 80, 180, 100], \"confidence\": 0.87},\n        ]\n\n    def readtext(self, *args, **kwargs) -> list[Any]:\n        return self.results\n\n\ndef test_server_init(server: EasyOCRServer) -> None:\n    assert server.current_language is None\n    assert server.reader is None\n\n\ndef test_server_health_endpoint(server: EasyOCRServer) -> None:\n    app = server._create_ocr_server()\n    client = TestClient(app)\n    response = client.get(\"/health\")\n    assert response.status_code == 200\n    assert response.json() == {\"status\": \"healthy\"}\n\n\ndef test_server_ocr_endpoint(server: EasyOCRServer) -> None:\n    image = Image.new(\"RGB\", (1, 1), color=(255, 255, 255))\n\n    # Save to bytes (to simulate a file upload)\n    buffer = io.BytesIO()\n    image.save(buffer, format=\"PNG\")\n    buffer.seek(0)\n    app = server._create_ocr_server()\n    mock_ocr = MockEasyOCRReader()\n    server.reader = mock_ocr  # type: ignore\n    server.current_language = \"en\"\n    client = TestClient(app)\n\n    response = client.post(\n        \"/ocr\",\n        files={\"file\": (\"test.png\", buffer, \"image/png\")},\n        data={\"language\": \"en\"},\n    )\n    assert response.status_code == 200\n    assert response.json().get(\"results\", []) == mock_ocr.transformed_results\n"
  },
  {
    "path": "ocr/paddleocr/Dockerfile",
    "content": "FROM ghcr.io/astral-sh/uv:python3.12-trixie\n\n# Install system dependencies\nRUN apt-get update && apt-get install -y \\\n    libgomp1 \\\n    libglib2.0-0 \\\n    libsm6 \\\n    libxext6 \\\n    libxrender-dev \\\n    libgl1 \\\n    && rm -rf /var/lib/apt/lists/*\n\n# Set working directory\nWORKDIR /app\n\n# Copy pyproject.toml and server code\nCOPY ./*py* .\n\n# install necessary dependencies\nRUN uv sync\n\n# Expose port\nEXPOSE 8829\n\n# Run server\nCMD [\"uv\", \"run\", \"python3\", \"server.py\"]\n"
  },
  {
    "path": "ocr/paddleocr/README.md",
    "content": "# PaddleOCR Service\n\nThis is a simple Flask server that wraps PaddleOCR to conform to the LiteParse OCR API specification (see `../../OCR_API_SPEC.md`).\n\nPaddleOCR is especially fast and accurate for Chinese, Japanese, and Korean languages.\n\n## Build and Run\n\n```bash\n# install and run (in one command)\nuv run server.py\n```\n\n## Usage\n\nThe service exposes a single endpoint:\n\n- `POST /ocr` - Perform OCR on an uploaded image\n\n### Parameters\n\n- `file` - Image file (multipart/form-data)\n- `language` - Language code (e.g., 'en', 'zh', 'ja', 'ko')\n\n### Example\n\n```bash\ncurl -X POST -F \"file=@image.png\" -F \"language=zh\" http://localhost:8829/ocr\n```\n\n### Response Format\n\n```json\n{\n  \"results\": [\n    {\n      \"text\": \"recognized text\",\n      \"bbox\": [x1, y1, x2, y2],\n      \"confidence\": 0.95\n    }\n  ]\n}\n```\n\nThis conforms to the LiteParse OCR API specification.\n\n## Supported Languages\n\nPaddleOCR supports 80+ languages with excellent support for CJK:\n\n- `en` - English\n- `zh` / `zh-cn` - Chinese (Simplified)\n- `zh-tw` / `zh-hant` - Chinese (Traditional)\n- `ja` - Japanese\n- `ko` - Korean\n- `fr` - French\n- `de` - German\n- `es` - Spanish\n- `pt` - Portuguese\n- `ru` - Russian\n- `ar` - Arabic\n- `hi` - Hindi/Devanagari\n\nFull list: https://github.com/PaddlePaddle/PaddleOCR\n\n## Performance\n\nPaddleOCR is optimized for speed and accuracy:\n\n- **Fast**: 2-3x faster than EasyOCR\n- **Accurate**: Especially for Asian languages (Chinese, Japanese, Korean)\n- **Lightweight**: Smaller model sizes\n\n## Use with LiteParse\n\nOnce the server is running, use it with LiteParse:\n\n```bash\n# Parse with PaddleOCR\nlit parse document.pdf --ocr-server-url http://localhost:8829/ocr\n\n# With specific language\nlit parse document.pdf --ocr-server-url http://localhost:8829/ocr --ocr-language zh\n```\n\nOr in code:\n\n```typescript\nimport { LiteParse } from 'liteparse';\n\nconst parser = new LiteParse({\n  ocrServerUrl: 'http://localhost:8829/ocr',\n  ocrLanguage: 'zh',\n});\n\nconst result = await parser.parse('document.pdf');\n```\n\n## Testing\n\nIf you make changes to the server, make sure to adapt and run tests:\n\n```bash\nuv run pytest test_server.py\n```\n\n## GPU Support\n\nFor GPU acceleration, set `use_gpu=True` in `server.py`.\n\n## Notes\n\n- First request may be slow as PaddleOCR downloads models\n- Models are cached after first use\n- Default port is 8829 (different from EasyOCR's 8828)\n"
  },
  {
    "path": "ocr/paddleocr/pyproject.toml",
    "content": "[project]\nname = \"paddleocr-liteparse\"\nversion = \"0.1.0\"\ndescription = \"Add your description here\"\nreadme = \"README.md\"\nrequires-python = \">=3.12,<3.14\"\ndependencies = [\n    \"fastapi>=0.131.0\",\n    \"numpy>=2.4.2\",\n    \"paddleocr>=3.4.0\",\n    \"paddlepaddle>=3.3.0\",\n    \"pillow>=12.1.1\",\n    \"python-multipart>=0.0.22\",\n    \"uvicorn>=0.41.0\",\n]\n\n[tool.uv.sources]\npaddlepaddle = { index = \"paddle\" }\n\n[[tool.uv.index]]\nname = \"paddle\"\nurl = \"https://www.paddlepaddle.org.cn/packages/stable/cpu/\"\nexplicit = true\n\n[dependency-groups]\ndev = [\n    \"httpx>=0.28.1\",\n    \"pytest>=9.0.2\",\n]\n"
  },
  {
    "path": "ocr/paddleocr/server.py",
    "content": "import io\nimport logging\nfrom typing import Any\n\nimport numpy as np\nimport uvicorn\nfrom fastapi import FastAPI, HTTPException\nfrom fastapi.datastructures import UploadFile\nfrom fastapi.param_functions import File, Form\nfrom paddleocr import PaddleOCR\nfrom PIL import Image\nfrom pydantic import BaseModel\n\n\nclass OcrResponse(BaseModel):\n    results: list[Any]\n\n\nclass StatusResponse(BaseModel):\n    status: str\n\n\nclass PaddleOCRServer:\n    def __init__(self) -> None:\n        self.ocr: PaddleOCR = PaddleOCR(\n            lang=\"en\",\n            use_doc_orientation_classify=False,\n            use_doc_unwarping=False,\n            use_textline_orientation=True,\n        )\n        self.current_language: str = \"en\"\n\n    @staticmethod\n    def normalize_language(language: str) -> str:\n        normalized = language.lower()\n        aliases = {\n            \"zh\": \"ch\",\n            \"zh-cn\": \"ch\",\n            \"zh-hans\": \"ch\",\n            \"zh-tw\": \"chinese_cht\",\n            \"zh-hant\": \"chinese_cht\",\n            \"ja\": \"japan\",\n            \"ko\": \"korean\",\n        }\n        return aliases.get(normalized, normalized)\n\n    def _create_ocr_server(\n        self,\n    ) -> FastAPI:\n        app = FastAPI()\n\n        @app.post(\"/ocr\")\n        async def ocr_endpoint(\n            file: UploadFile = File(...), language: str = Form(default=\"en\")\n        ) -> OcrResponse:\n            # Get language from request\n            language = self.normalize_language(language)\n\n            try:\n                # Initialize OCR if needed or language changed\n                if self.current_language != language:\n                    # PaddleOCR 3.x parameters\n                    self.ocr = PaddleOCR(\n                        lang=language,\n                        use_doc_orientation_classify=False,\n                        use_doc_unwarping=False,\n                        use_textline_orientation=True,\n                    )\n                    self.current_language = language\n\n                # Load image\n\n                image_data = await file.read()\n                image = Image.open(io.BytesIO(image_data))\n\n                # Convert to numpy array (RGB)\n                if image.mode != \"RGB\":\n                    image = image.convert(\"RGB\")\n                image_array = np.array(image)\n\n                # Run OCR\n                # PaddleOCR 3.x returns: list of result dicts\n                # Each result has: res['rec_texts'], res['rec_scores'], res['rec_boxes']\n                results = self.ocr.predict(image_array)\n            except ValueError as ve:\n                if \"No models are available for the language\" in str(ve):\n                    raise HTTPException(status_code=400, detail=str(ve))\n                raise HTTPException(status_code=500, detail=str(ve))\n            except Exception as e:\n                raise HTTPException(status_code=500, detail=str(e))\n\n            # Format results according to LiteParse OCR API spec\n            # Convert to: { text, bbox: [x1, y1, x2, y2], confidence }\n            formatted = []\n\n            if results and len(results) > 0:\n                # Get the first result\n                result = results[0]\n\n                res_data = (\n                    result.get(\"res\", result) if isinstance(result, dict) else result\n                )\n                # Extract texts, scores, and boxes from the result\n                if isinstance(res_data, dict):\n                    texts = res_data.get(\"rec_texts\", [])\n                    scores = res_data.get(\"rec_scores\", [])\n                    boxes = res_data.get(\"rec_boxes\", [])\n                else:\n                    # Fallback for result object with attributes\n                    texts = getattr(res_data, \"rec_texts\", []) or []\n                    scores = getattr(res_data, \"rec_scores\", []) or []\n                    boxes = getattr(res_data, \"rec_boxes\", []) or []\n\n                # Convert numpy arrays to lists if needed\n                if hasattr(texts, \"tolist\"):\n                    texts = texts.tolist()\n                if hasattr(scores, \"tolist\"):\n                    scores = scores.tolist()\n                if hasattr(boxes, \"tolist\"):\n                    boxes = boxes.tolist()\n\n                # Combine them - they should be parallel arrays\n                for i in range(len(texts)):\n                    text = texts[i]\n                    confidence = float(scores[i]) if i < len(scores) else 0.0\n\n                    # Get bounding box coordinates\n                    # rec_boxes format is typically [x_min, y_min, x_max, y_max]\n                    if i < len(boxes):\n                        box = boxes[i]\n                        # Convert to list and ensure 4 coordinates\n                        if hasattr(box, \"tolist\"):\n                            bbox = box.tolist()\n                        else:\n                            bbox = list(box)\n                    else:\n                        bbox = [0, 0, 0, 0]\n\n                    formatted.append(\n                        {\"text\": text, \"bbox\": bbox, \"confidence\": confidence}\n                    )\n\n            return OcrResponse(results=formatted)\n\n        @app.get(\"/health\")\n        def health() -> StatusResponse:\n            return StatusResponse(status=\"healthy\")\n\n        return app\n\n    def serve(self) -> None:\n        app = self._create_ocr_server()\n        uvicorn.run(app, host=\"0.0.0.0\", port=8829)\n\n\nif __name__ == \"__main__\":\n    logging.basicConfig(\n        level=logging.DEBUG,\n    )\n    logging.info(\"Starting server on port 8829\")\n    server = PaddleOCRServer()\n    server.serve()\n"
  },
  {
    "path": "ocr/paddleocr/test_server.py",
    "content": "import io\nfrom typing import Any\n\nimport pytest\nfrom fastapi.testclient import TestClient\nfrom paddleocr import PaddleOCR\nfrom PIL import Image\n\nimport server as paddle_server_module\nfrom server import PaddleOCRServer\n\n\n@pytest.fixture(scope=\"module\")\ndef server() -> PaddleOCRServer:\n    return PaddleOCRServer()\n\n\nclass MockPaddleOcr:\n    def __init__(self, *args, **kwargs) -> None:\n        self.results = [\n            {\n                \"res\": {\n                    \"rec_texts\": [\"Hello World\", \"Total: $42.00\", \"Thank you!\"],\n                    \"rec_scores\": [0.98, 0.95, 0.87],\n                    \"rec_boxes\": [\n                        [10, 20, 200, 40],\n                        [10, 50, 250, 70],\n                        [10, 80, 180, 100],\n                    ],\n                }\n            }\n        ]\n        self.transformed_results = [\n            {\"text\": \"Hello World\", \"bbox\": [10, 20, 200, 40], \"confidence\": 0.98},\n            {\"text\": \"Total: $42.00\", \"bbox\": [10, 50, 250, 70], \"confidence\": 0.95},\n            {\"text\": \"Thank you!\", \"bbox\": [10, 80, 180, 100], \"confidence\": 0.87},\n        ]\n\n    def predict(self, *args, **kwargs) -> list[Any]:\n        return self.results\n\n\ndef test_server_init(server: PaddleOCRServer) -> None:\n    assert server.current_language == \"en\"\n    assert isinstance(server.ocr, PaddleOCR)\n\n\ndef test_server_health_endpoint(server: PaddleOCRServer) -> None:\n    app = server._create_ocr_server()\n    client = TestClient(app)\n    response = client.get(\"/health\")\n    assert response.status_code == 200\n    assert response.json() == {\"status\": \"healthy\"}\n\n\ndef test_server_ocr_endpoint(server: PaddleOCRServer) -> None:\n    image = Image.new(\"RGB\", (1, 1), color=(255, 255, 255))\n\n    # Save to bytes (to simulate a file upload)\n    buffer = io.BytesIO()\n    image.save(buffer, format=\"PNG\")\n    buffer.seek(0)\n    app = server._create_ocr_server()\n    mock_ocr = MockPaddleOcr()\n    server.ocr = mock_ocr  # type: ignore\n    client = TestClient(app)\n\n    response = client.post(\n        \"/ocr\",\n        files={\"file\": (\"test.png\", buffer, \"image/png\")},\n        data={\"language\": \"en\"},\n    )\n    assert response.status_code == 200\n    assert response.json().get(\"results\", []) == mock_ocr.transformed_results\n\n\ndef test_server_normalizes_documented_language_aliases(\n    monkeypatch: pytest.MonkeyPatch,\n) -> None:\n    image = Image.new(\"RGB\", (1, 1), color=(255, 255, 255))\n    buffer = io.BytesIO()\n    image.save(buffer, format=\"PNG\")\n    buffer.seek(0)\n\n    captured_langs: list[str] = []\n\n    class CapturingPaddleOcr(MockPaddleOcr):\n        def __init__(self, *args, **kwargs) -> None:\n            captured_langs.append(kwargs.get(\"lang\", \"\"))\n            super().__init__(*args, **kwargs)\n\n    monkeypatch.setattr(paddle_server_module, \"PaddleOCR\", CapturingPaddleOcr)\n\n    server = PaddleOCRServer()\n    app = server._create_ocr_server()\n    client = TestClient(app)\n\n    response = client.post(\n        \"/ocr\",\n        files={\"file\": (\"test.png\", buffer, \"image/png\")},\n        data={\"language\": \"zh\"},\n    )\n\n    assert response.status_code == 200\n    assert captured_langs == [\"en\", \"ch\"]\n    assert server.current_language == \"ch\"\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"@llamaindex/liteparse\",\n  \"version\": \"1.4.6\",\n  \"description\": \"Open-source PDF parsing with spatial text extraction and OCR processing\",\n  \"type\": \"module\",\n  \"main\": \"./dist/src/lib.js\",\n  \"types\": \"./dist/src/lib.d.ts\",\n  \"bin\": {\n    \"lit\": \"./dist/src/index.js\",\n    \"liteparse\": \"./dist/src/index.js\"\n  },\n  \"exports\": {\n    \".\": {\n      \"types\": \"./dist/src/lib.d.ts\",\n      \"import\": \"./dist/src/lib.js\"\n    },\n    \"./package.json\": \"./package.json\"\n  },\n  \"files\": [\n    \"dist\",\n    \"src/vendor/pdfjs\",\n    \"README.md\",\n    \"LICENSE\"\n  ],\n  \"scripts\": {\n    \"build\": \"tsc && npm run copy-vendor\",\n    \"build:windows\": \"tsc && npm run copy-vendor:windows\",\n    \"copy-vendor\": \"mkdir -p dist/src/vendor && cp -r src/vendor/pdfjs dist/src/vendor/\",\n    \"copy-vendor:windows\": \"powershell -Command \\\"New-Item -ItemType Directory -Path dist/src/vendor -Force; Copy-Item -Recurse src/vendor/pdfjs dist/src/vendor/\\\"\",\n    \"dev\": \"tsc --watch\",\n    \"test\": \"vitest run\",\n    \"test:watch\": \"vitest\",\n    \"lint\": \"eslint src cli\",\n    \"lint:fix\": \"eslint src cli --fix\",\n    \"format\": \"prettier --write \\\"src/**/*.ts\\\" \\\"cli/**/*.ts\\\"\",\n    \"format:check\": \"prettier --check \\\"src/**/*.ts\\\" \\\"cli/**/*.ts\\\"\",\n    \"docs:api\": \"bash scripts/generate-api-docs.sh\",\n    \"changeset\": \"changeset\",\n    \"version\": \"changeset version\",\n    \"release\": \"npm run build && changeset publish\"\n  },\n  \"dependencies\": {\n    \"@hyzyla/pdfium\": \"^2.1.9\",\n    \"axios\": \"^1.7.0\",\n    \"commander\": \"^12.0.0\",\n    \"file-type\": \"^21.3.3\",\n    \"form-data\": \"^4.0.0\",\n    \"p-limit\": \"^7.3.0\",\n    \"sharp\": \"^0.34.5\",\n    \"tesseract.js\": \"^7.0.0\",\n    \"unified\": \"^11.0.0\",\n    \"zod\": \"^3.23.0\"\n  },\n  \"devDependencies\": {\n    \"@changesets/changelog-github\": \"^0.6.0\",\n    \"@changesets/cli\": \"^2.30.0\",\n    \"@eslint/js\": \"^10.0.1\",\n    \"@types/node\": \"^22.0.0\",\n    \"eslint\": \"^10.0.0\",\n    \"eslint-config-prettier\": \"^10.1.8\",\n    \"eslint-plugin-prettier\": \"^5.5.5\",\n    \"prettier\": \"^3.8.1\",\n    \"typedoc\": \"^0.28.17\",\n    \"typedoc-plugin-markdown\": \"^4.10.0\",\n    \"typescript\": \"~5.9.2\",\n    \"typescript-eslint\": \"^8.56.0\",\n    \"vitest\": \"^4.0.18\"\n  },\n  \"engines\": {\n    \"node\": \">=18.0.0\"\n  },\n  \"keywords\": [\n    \"pdf\",\n    \"parser\",\n    \"ocr\",\n    \"text-extraction\",\n    \"pdf-to-text\",\n    \"document-parsing\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/run-llama/liteparse.git\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/run-llama/liteparse/issues\"\n  },\n  \"homepage\": \"https://github.com/run-llama/liteparse#readme\",\n  \"author\": \"LlamaIndex\",\n  \"license\": \"Apache-2.0\"\n}\n"
  },
  {
    "path": "packages/python/README.md",
    "content": "# LiteParse Python\n\nPython wrapper for [LiteParse](https://github.com/run-llama/liteparse) - fast, lightweight document parsing with optional OCR.\n\n> **Important:** This package is a Python wrapper around the LiteParse Node.js CLI.\n> You must have **Node.js** (>= 18) installed on your system. The CLI will be auto-installed\n> via npm on first use if not already present, or you can install it manually beforehand.\n\n## Installation\n\n### Step 1: Install Node.js\n\nLiteParse requires Node.js (>= 18). Install it from [nodejs.org](https://nodejs.org/) or via your package manager.\n\n### Step 2: Install the LiteParse CLI\n\n```bash\nnpm install -g @llamaindex/liteparse\n```\n\n### Step 3: Install the Python package\n\n```bash\npip install liteparse\n```\n\n> **Note:** If you skip Step 2, the Python package will attempt to auto-install the CLI\n> via `npm install -g @llamaindex/liteparse` on first use (requires npm in your PATH).\n\n## Quick Start\n\n```python\nfrom liteparse import LiteParse\n\n# Create parser\nparser = LiteParse()\n\n# Parse a document\nresult = parser.parse(\"document.pdf\")\nprint(result.text)\n\n# Access structured data\nfor page in result.pages:\n    print(f\"Page {page.pageNum}: {len(page.textItems)} text items\")\n```\n\n## Configuration\n\nAll parsing options are passed per-call to `parse()`:\n\n```python\nfrom liteparse import LiteParse\n\nparser = LiteParse()\n\nresult = parser.parse(\n    \"document.pdf\",\n    ocr_enabled=False,\n    max_pages=10,\n    dpi=150,\n    preserve_very_small_text=True,\n)\nprint(result.text)\n```\n\n## Parsing from bytes\n\nIf you already have file contents in memory (e.g. from a web upload), pass them directly:\n\n```python\nwith open(\"document.pdf\", \"rb\") as f:\n    pdf_bytes = f.read()\n\nresult = parser.parse(pdf_bytes)\nprint(result.text)\n```\n\n## Batch Processing\n\nFor parsing multiple files, batch mode is significantly faster as it reuses the PDF engine:\n\n```python\nfrom liteparse import LiteParse\n\nparser = LiteParse()\n\n# Parse all documents in a directory\nresult = parser.batch_parse(\n    input_dir=\"./documents\",\n    output_dir=\"./output\",\n    ocr_enabled=False,\n    recursive=True,              # Include subdirectories\n    extension_filter=\".pdf\",     # Only PDF files\n)\n\nprint(f\"Output written to: {result.output_dir}\")\n```\n\n## Supported Formats\n\n- PDF (`.pdf`)\n- Microsoft Office (`.docx`, `.xlsx`, `.pptx`, etc.) - requires LibreOffice\n- OpenDocument (`.odt`, `.ods`, `.odp`) - requires LibreOffice\n- Images (`.png`, `.jpg`, `.tiff`, etc.) - requires ImageMagick\n- And more!\n\n## Performance Tips\n\n1. **Disable OCR** if your documents have selectable text:\n   ```python\n   result = parser.parse(\"doc.pdf\", ocr_enabled=False)\n   ```\n\n2. **Use batch mode** for multiple files to avoid cold-start overhead:\n   ```python\n   parser.batch_parse(\"./input\", \"./output\")\n   ```\n\n3. **Limit pages** if you only need specific pages:\n   ```python\n   result = parser.parse(\"doc.pdf\", target_pages=\"1-5\")\n   ```\n"
  },
  {
    "path": "packages/python/liteparse/__init__.py",
    "content": "from .parser import LiteParse\nfrom .types import (\n    # Enums\n    OutputFormat,\n    ImageFormat,\n    # Results\n    ParseResult,\n    BatchResult,\n    ParsedPage,\n    TextItem,\n    BoundingBox,\n    ScreenshotResult,\n    ScreenshotBatchResult,\n    # Errors\n    ParseError,\n    CLINotFoundError,\n)\n\n__version__ = \"1.2.1\"\n__all__ = [\n    # Main class\n    \"LiteParse\",\n    # Enums\n    \"OutputFormat\",\n    \"ImageFormat\",\n    # Results\n    \"ParseResult\",\n    \"BatchResult\",\n    \"ParsedPage\",\n    \"TextItem\",\n    \"BoundingBox\",\n    \"ScreenshotResult\",\n    \"ScreenshotBatchResult\",\n    # Errors\n    \"ParseError\",\n    \"CLINotFoundError\",\n]\n"
  },
  {
    "path": "packages/python/liteparse/parser.py",
    "content": "\"\"\"LiteParse Python wrapper - wraps the Node.js CLI via subprocess.\"\"\"\n\nimport asyncio\nimport json\nimport os\nimport shutil\nimport subprocess\nimport tempfile\nimport warnings\nfrom pathlib import Path\nfrom typing import Any, List, Literal, Optional, Union, cast\n\nfrom .types import (\n    BatchResult,\n    BoundingBox,\n    CLINotFoundError,\n    ImageFormat,\n    OutputFormat,\n    ParsedPage,\n    ParseError,\n    ParseResult,\n    ScreenshotBatchResult,\n    ScreenshotResult,\n    TextItem,\n)\n\n\ndef _find_cli(install_if_not_available: bool) -> str:\n    \"\"\"Find the liteparse CLI executable.\"\"\"\n    # Check if liteparse is in PATH\n    cli_path = shutil.which(\"liteparse\")\n    if cli_path:\n        return cli_path\n\n    # Check if npx is available\n    npx_path = shutil.which(\"npx\")\n    if npx_path:\n        return \"npx @llamaindex/liteparse\"\n\n    # Check common node_modules locations\n    possible_paths = [\n        \"./node_modules/.bin/liteparse\",\n        \"../node_modules/.bin/liteparse\",\n        \"../../node_modules/.bin/liteparse\",\n    ]\n\n    for path in possible_paths:\n        if os.path.isfile(path):\n            return os.path.abspath(path)\n\n    if install_if_not_available:\n        npm_path = shutil.which(\"npm\")\n        if not npm_path:\n            raise CLINotFoundError(\n                \"liteparse CLI not found and npm is not available to auto-install it.\\n\"\n                \"Please install Node.js (>= 18) from https://nodejs.org/ and then run:\\n\"\n                \"  npm install -g @llamaindex/liteparse\"\n            )\n        warnings.warn(\n            \"liteparse CLI could not be found. Running `npm install -g @llamaindex/liteparse` to install it.\",\n            UserWarning,\n            stacklevel=2,\n        )\n        result = subprocess.run(\n            [\"npm\", \"install\", \"-g\", \"@llamaindex/liteparse\"],\n        )\n        if result.returncode != 0:\n            raise subprocess.CalledProcessError(\n                result.returncode,\n                [\"npm\", \"install\", \"-g\", \"@llamaindex/liteparse\"],\n                result.stderr,\n            )\n        cli_path = shutil.which(\"liteparse\")\n        if cli_path:\n            return cli_path\n\n    raise CLINotFoundError(\n        \"liteparse CLI not found. Please install Node.js (>= 18) and then run:\\n\"\n        \"  npm install -g @llamaindex/liteparse\"\n    )\n\n\ndef _parse_json_result(json_data: dict) -> ParseResult:\n    \"\"\"Parse JSON output from CLI into ParseResult.\"\"\"\n    pages: List[ParsedPage] = []\n\n    for page_data in json_data.get(\"pages\", []):\n        # Parse text items\n        text_items: List[TextItem] = []\n        for item in page_data.get(\"textItems\", []):\n            text_items.append(\n                TextItem(\n                    text=item.get(\"text\", \"\"),\n                    x=item.get(\"x\", 0),\n                    y=item.get(\"y\", 0),\n                    width=item.get(\"width\", 0),\n                    height=item.get(\"height\", 0),\n                    confidence=item.get(\"confidence\"),\n                    fontName=item.get(\"fontName\"),\n                    fontSize=item.get(\"fontSize\"),\n                )\n            )\n\n        # Parse bounding boxes\n        bounding_boxes: List[BoundingBox] = []\n        for bbox in page_data.get(\"boundingBoxes\", []):\n            bounding_boxes.append(\n                BoundingBox(\n                    x1=bbox.get(\"x1\", 0),\n                    y1=bbox.get(\"y1\", 0),\n                    x2=bbox.get(\"x2\", 0),\n                    y2=bbox.get(\"y2\", 0),\n                )\n            )\n\n        pages.append(\n            ParsedPage(\n                pageNum=page_data.get(\"page\", page_data.get(\"pageNum\", 0)),\n                width=page_data.get(\"width\", 0),\n                height=page_data.get(\"height\", 0),\n                text=page_data.get(\"text\", \"\"),\n                textItems=text_items,\n                boundingBoxes=bounding_boxes,\n            )\n        )\n\n    # Build full text from pages (JSON doesn't have top-level text field)\n    full_text = \"\\n\\n\".join(page.text for page in pages)\n\n    return ParseResult(\n        pages=pages,\n        text=full_text,\n        json=json_data,\n    )\n\n\ndef _build_parse_cli_args(\n    ocr_enabled: bool,\n    ocr_server_url: Optional[str],\n    ocr_language: str,\n    num_workers: Optional[int],\n    max_pages: int,\n    target_pages: Optional[str],\n    dpi: int,\n    precise_bounding_box: bool,\n    preserve_very_small_text: bool,\n    password: Optional[str],\n) -> List[str]:\n    \"\"\"Build CLI arguments for parse command.\"\"\"\n    args: List[str] = [\"--format\", \"json\"]\n\n    if not ocr_enabled:\n        args.append(\"--no-ocr\")\n    elif ocr_server_url:\n        args.extend([\"--ocr-server-url\", ocr_server_url])\n\n    args.extend([\"--ocr-language\", ocr_language])\n\n    if num_workers is not None:\n        args.extend([\"--num-workers\", str(num_workers)])\n\n    args.extend([\"--max-pages\", str(max_pages)])\n\n    if target_pages:\n        args.extend([\"--target-pages\", target_pages])\n\n    args.extend([\"--dpi\", str(dpi)])\n\n    if not precise_bounding_box:\n        args.append(\"--no-precise-bbox\")\n\n    if preserve_very_small_text:\n        args.append(\"--preserve-small-text\")\n\n    if password:\n        args.extend([\"--password\", password])\n\n    args.append(\"-q\")\n    return args\n\n\ndef _build_batch_cli_args(\n    output_format: OutputFormat,\n    ocr_enabled: bool,\n    ocr_server_url: Optional[str],\n    ocr_language: str,\n    num_workers: Optional[int],\n    max_pages: int,\n    dpi: int,\n    precise_bounding_box: bool,\n    recursive: bool,\n    extension_filter: Optional[str],\n    password: Optional[str],\n) -> List[str]:\n    \"\"\"Build CLI arguments for batch-parse command.\"\"\"\n    args: List[str] = [\"--format\", output_format.value]\n\n    if not ocr_enabled:\n        args.append(\"--no-ocr\")\n    elif ocr_server_url:\n        args.extend([\"--ocr-server-url\", ocr_server_url])\n\n    args.extend([\"--ocr-language\", ocr_language])\n\n    if num_workers is not None:\n        args.extend([\"--num-workers\", str(num_workers)])\n\n    args.extend([\"--max-pages\", str(max_pages)])\n    args.extend([\"--dpi\", str(dpi)])\n\n    if not precise_bounding_box:\n        args.append(\"--no-precise-bbox\")\n\n    if recursive:\n        args.append(\"--recursive\")\n\n    if extension_filter:\n        args.extend([\"--extension\", extension_filter])\n\n    if password:\n        args.extend([\"--password\", password])\n\n    args.append(\"-q\")\n    return args\n\n\nclass LiteParse:\n    \"\"\"\n    Python wrapper for the LiteParse document parser.\n\n    This class wraps the LiteParse Node.js CLI, providing a Pythonic interface\n    for parsing PDFs and other documents.\n\n    Example:\n        >>> from liteparse import LiteParse\n        >>> parser = LiteParse()\n        >>> result = parser.parse(\"document.pdf\")\n        >>> print(result.text)\n    \"\"\"\n\n    def __init__(\n        self, cli_path: Optional[str] = None, install_if_not_available: bool = True\n    ):\n        \"\"\"\n        Initialize LiteParse parser.\n\n        Args:\n            cli_path: Custom path to liteparse CLI (auto-detected if not provided)\n            install_if_not_available: Install the liteparse CLI from NPM if not available. Defaults to True.\n        \"\"\"\n        self._cli_path = cli_path\n        self.install_if_not_available = install_if_not_available\n\n    @property\n    def cli_path(self) -> str:\n        \"\"\"Get the CLI path, finding it if not already set.\"\"\"\n        if self._cli_path is None:\n            self._cli_path = _find_cli(self.install_if_not_available)\n        return self._cli_path\n\n    def _prepare_command(\n        self,\n        subcommand: Literal[\"parse\", \"batch-parse\", \"screenshot\"],\n        *positional: Any,\n        **options: Any,\n    ) -> list[str]:\n        cmd_parts = self.cli_path.split()\n        cmd = cmd_parts + [subcommand, *positional]\n        if subcommand == \"parse\":\n            cmd.extend(_build_parse_cli_args(**options))\n        elif subcommand == \"batch-parse\":\n            cmd.extend(_build_batch_cli_args(**options))\n        return cmd\n\n    @staticmethod\n    def _extract_path_and_bytes(\n        file_data: Union[str, Path, bytes],\n    ) -> tuple[str, Union[bytes, None]]:\n        if not isinstance(file_data, bytes):\n            file_path = Path(file_data)\n            if not file_path.exists():\n                raise FileNotFoundError(f\"File not found: {file_path}\")\n            file_path = str(file_path.absolute())\n            file_bytes = None\n        else:\n            file_path = \"-\"\n            file_bytes = file_data\n        return file_path, file_bytes\n\n    @staticmethod\n    def _extract_batch_params(\n        input_dir: Union[str, Path],\n        output_dir: Union[str, Path],\n        output_format: Union[OutputFormat, str],\n    ) -> tuple[Path, Path, OutputFormat]:\n        indir = Path(input_dir)\n        outdir = Path(output_dir)\n\n        if not indir.exists():\n            raise FileNotFoundError(f\"Input directory not found: {input_dir}\")\n\n        if isinstance(output_format, str):\n            output_format = OutputFormat(output_format)\n\n        return indir, outdir, output_format\n\n    @staticmethod\n    def _extract_screenshot_params(\n        file_path: Union[str, Path],\n        image_format: Union[ImageFormat, str],\n        output_dir: Union[str, Path, None],\n    ) -> tuple[Path, ImageFormat, Path]:\n        file_path = Path(file_path)\n        if not file_path.exists():\n            raise FileNotFoundError(f\"File not found: {file_path}\")\n\n        if isinstance(image_format, str):\n            image_format = ImageFormat(image_format)\n\n        # Use temp dir if output_dir not provided\n        if output_dir is None:\n            output_dir = Path(tempfile.mkdtemp(prefix=\"liteparse_screenshots_\"))\n        else:\n            output_dir = Path(output_dir)\n            output_dir.mkdir(parents=True, exist_ok=True)\n        return file_path, image_format, output_dir\n\n    @staticmethod\n    def _get_parse_result(\n        returncode: int,\n        stdout: bytes,\n        stderr: bytes,\n    ) -> ParseResult:\n        if returncode != 0:\n            raise ParseError(\n                f\"Parsing failed with exit code {returncode}\",\n                stderr=stderr.decode(\"utf-8\"),\n            )\n        try:\n            json_data = json.loads(stdout.decode(\"utf-8\"))\n            return _parse_json_result(json_data)\n        except json.JSONDecodeError as e:\n            raise ParseError(f\"Failed to parse CLI output: {e}\")\n\n    @staticmethod\n    def _get_screenshot_result(\n        returncode: int,\n        stderr: str,\n        output_dir: Path,\n        image_format: ImageFormat,\n        load_bytes: bool,\n    ) -> ScreenshotBatchResult:\n        if returncode != 0:\n            raise ParseError(\n                f\"Screenshot generation failed with exit code {returncode}\",\n                stderr=stderr,\n            )\n        screenshots: List[ScreenshotResult] = []\n        ext = f\".{image_format.value}\"\n\n        for img_file in sorted(output_dir.glob(f\"*{ext}\")):\n            # Parse page number from filename (page_N.png)\n            filename = img_file.stem\n            if filename.startswith(\"page_\"):\n                try:\n                    page_num = int(filename.replace(\"page_\", \"\"))\n                except ValueError:\n                    continue\n\n                # Optionally load bytes\n                image_bytes = None\n                if load_bytes:\n                    image_bytes = img_file.read_bytes()\n\n                screenshots.append(\n                    ScreenshotResult(\n                        page_num=page_num,\n                        image_path=str(img_file),\n                        image_bytes=image_bytes,\n                    )\n                )\n\n        return ScreenshotBatchResult(\n            screenshots=screenshots,\n            output_dir=str(output_dir),\n        )\n\n    def parse(\n        self,\n        file_data: Union[str, Path, bytes],\n        *,\n        ocr_enabled: bool = True,\n        ocr_server_url: Optional[str] = None,\n        ocr_language: str = \"en\",\n        num_workers: Optional[int] = None,\n        max_pages: int = 10000,\n        target_pages: Optional[str] = None,\n        dpi: int = 150,\n        precise_bounding_box: bool = True,\n        preserve_very_small_text: bool = False,\n        password: Optional[str] = None,\n        timeout: Optional[float] = None,\n    ) -> ParseResult:\n        \"\"\"\n        Parse a document file.\n\n        Args:\n            file_path: Path to the document file (PDF, DOCX, images, etc.)\n            file_bytes: Bytes content of the file\n            ocr_enabled: Whether to enable OCR for scanned documents\n            ocr_server_url: URL of HTTP OCR server (uses Tesseract if not provided)\n            ocr_language: Language code for OCR (e.g., \"en\", \"fr\", \"de\")\n            num_workers: Number of pages to OCR in parallel (defaults to CPU cores - 1)\n            max_pages: Maximum number of pages to parse\n            target_pages: Specific pages to parse (e.g., \"1-5,10,15-20\")\n            dpi: DPI for rendering (affects OCR quality)\n            precise_bounding_box: Whether to compute precise bounding boxes\n            preserve_very_small_text: Whether to preserve very small text\n            password: Password for encrypted/protected documents\n            timeout: Timeout in seconds (None for no timeout)\n\n        Returns:\n            ParseResult containing the parsed document data\n\n        Raises:\n            ParseError: If parsing fails\n            FileNotFoundError: If the file doesn't exist\n            TimeoutError: If parsing times out\n        \"\"\"\n\n        file_path, file_bytes = self._extract_path_and_bytes(file_data)\n\n        # Build command\n        cmd = self._prepare_command(\n            \"parse\",\n            file_path,\n            ocr_enabled=ocr_enabled,\n            ocr_server_url=ocr_server_url,\n            ocr_language=ocr_language,\n            num_workers=num_workers,\n            max_pages=max_pages,\n            target_pages=target_pages,\n            dpi=dpi,\n            precise_bounding_box=precise_bounding_box,\n            preserve_very_small_text=preserve_very_small_text,\n            password=password,\n        )\n\n        try:\n            result = subprocess.run(\n                cmd,\n                capture_output=True,\n                timeout=timeout,\n                check=False,\n                input=file_bytes,\n            )\n\n            return self._get_parse_result(\n                result.returncode, result.stdout, result.stderr\n            )\n\n        except subprocess.TimeoutExpired:\n            raise TimeoutError(f\"Parsing timed out after {timeout} seconds\")\n\n    async def parse_async(\n        self,\n        file_data: Union[str, Path, bytes],\n        *,\n        ocr_enabled: bool = True,\n        ocr_server_url: Optional[str] = None,\n        ocr_language: str = \"en\",\n        num_workers: Optional[int] = None,\n        max_pages: int = 10000,\n        target_pages: Optional[str] = None,\n        dpi: int = 150,\n        precise_bounding_box: bool = True,\n        preserve_very_small_text: bool = False,\n        password: Optional[str] = None,\n        timeout: Optional[float] = None,\n    ) -> ParseResult:\n        \"\"\"\n        Parse a document file (asynchronously).\n\n        Args:\n            file_path: Path to the document file (PDF, DOCX, images, etc.)\n            file_bytes: Bytes content of the file\n            ocr_enabled: Whether to enable OCR for scanned documents\n            ocr_server_url: URL of HTTP OCR server (uses Tesseract if not provided)\n            ocr_language: Language code for OCR (e.g., \"en\", \"fr\", \"de\")\n            num_workers: Number of pages to OCR in parallel (defaults to CPU cores - 1)\n            max_pages: Maximum number of pages to parse\n            target_pages: Specific pages to parse (e.g., \"1-5,10,15-20\")\n            dpi: DPI for rendering (affects OCR quality)\n            precise_bounding_box: Whether to compute precise bounding boxes\n            preserve_very_small_text: Whether to preserve very small text\n            password: Password for encrypted/protected documents\n            timeout: Timeout in seconds (None for no timeout)\n\n        Returns:\n            ParseResult containing the parsed document data\n\n        Raises:\n            ParseError: If parsing fails\n            FileNotFoundError: If the file doesn't exist\n            TimeoutError: If parsing times out\n        \"\"\"\n        file_path, file_bytes = self._extract_path_and_bytes(file_data)\n\n        # Build command\n        cmd = self._prepare_command(\n            \"parse\",\n            file_path,\n            ocr_enabled=ocr_enabled,\n            ocr_server_url=ocr_server_url,\n            ocr_language=ocr_language,\n            num_workers=num_workers,\n            max_pages=max_pages,\n            target_pages=target_pages,\n            dpi=dpi,\n            precise_bounding_box=precise_bounding_box,\n            preserve_very_small_text=preserve_very_small_text,\n            password=password,\n        )\n\n        try:\n            process = await asyncio.subprocess.create_subprocess_exec(\n                cmd[0],\n                *cmd[1:],\n                stdin=asyncio.subprocess.PIPE,\n                stdout=asyncio.subprocess.PIPE,\n                stderr=asyncio.subprocess.PIPE,\n            )\n            stdout, stderr = await asyncio.wait_for(\n                process.communicate(input=file_bytes), timeout=timeout\n            )\n\n            return self._get_parse_result(cast(int, process.returncode), stdout, stderr)\n\n        except TimeoutError:\n            raise TimeoutError(f\"Parsing timed out after {timeout} seconds\")\n\n    def batch_parse(\n        self,\n        input_dir: Union[str, Path],\n        output_dir: Union[str, Path],\n        *,\n        output_format: Union[OutputFormat, str] = OutputFormat.TEXT,\n        ocr_enabled: bool = True,\n        ocr_server_url: Optional[str] = None,\n        ocr_language: str = \"en\",\n        num_workers: Optional[int] = None,\n        max_pages: int = 10000,\n        dpi: int = 150,\n        precise_bounding_box: bool = True,\n        recursive: bool = False,\n        extension_filter: Optional[str] = None,\n        password: Optional[str] = None,\n        timeout: Optional[float] = None,\n    ) -> BatchResult:\n        \"\"\"\n        Parse multiple documents in batch mode.\n\n        This is more efficient than calling parse() multiple times because\n        it reuses the PDF engine across files, avoiding cold-start overhead.\n\n        Args:\n            input_dir: Directory containing documents to parse\n            output_dir: Directory to write output files\n            output_format: Output format (\"json\" or \"text\")\n            ocr_enabled: Whether to enable OCR for scanned documents\n            ocr_server_url: URL of HTTP OCR server (uses Tesseract if not provided)\n            ocr_language: Language code for OCR\n            num_workers: Number of pages to OCR in parallel (defaults to CPU cores - 1)\n            max_pages: Maximum number of pages to parse per file\n            dpi: DPI for rendering\n            precise_bounding_box: Whether to compute precise bounding boxes\n            recursive: Whether to recursively search subdirectories\n            extension_filter: Only process files with this extension (e.g., \".pdf\")\n            password: Password for encrypted/protected documents (applied to all files)\n            timeout: Timeout in seconds for the entire batch\n\n        Returns:\n            BatchResult with output directory path\n\n        Raises:\n            FileNotFoundError: If the input directory doesn't exist\n            TimeoutError: If the batch operation times out\n        \"\"\"\n\n        input_dir, output_dir, output_format = self._extract_batch_params(\n            input_dir, output_dir, output_format\n        )\n\n        # Build command\n        cmd = self._prepare_command(\n            \"batch-parse\",\n            str(input_dir.absolute()),\n            str(output_dir.absolute()),\n            output_format=output_format,\n            ocr_enabled=ocr_enabled,\n            ocr_server_url=ocr_server_url,\n            ocr_language=ocr_language,\n            num_workers=num_workers,\n            max_pages=max_pages,\n            dpi=dpi,\n            precise_bounding_box=precise_bounding_box,\n            recursive=recursive,\n            extension_filter=extension_filter,\n            password=password,\n        )\n\n        try:\n            subprocess.run(\n                cmd,\n                capture_output=True,\n                text=True,\n                timeout=timeout,\n                check=False,\n            )\n\n            return BatchResult(output_dir=str(output_dir))\n\n        except subprocess.TimeoutExpired:\n            raise TimeoutError(f\"Batch parsing timed out after {timeout} seconds\")\n\n    async def batch_parse_async(\n        self,\n        input_dir: Union[str, Path],\n        output_dir: Union[str, Path],\n        *,\n        output_format: Union[OutputFormat, str] = OutputFormat.TEXT,\n        ocr_enabled: bool = True,\n        ocr_server_url: Optional[str] = None,\n        ocr_language: str = \"en\",\n        num_workers: Optional[int] = None,\n        max_pages: int = 10000,\n        dpi: int = 150,\n        precise_bounding_box: bool = True,\n        recursive: bool = False,\n        extension_filter: Optional[str] = None,\n        password: Optional[str] = None,\n        timeout: Optional[float] = None,\n    ) -> BatchResult:\n        \"\"\"\n        Parse multiple documents in batch mode (asynchronously).\n\n        This is more efficient than calling parse() multiple times because\n        it reuses the PDF engine across files, avoiding cold-start overhead.\n\n        Args:\n            input_dir: Directory containing documents to parse\n            output_dir: Directory to write output files\n            output_format: Output format (\"json\" or \"text\")\n            ocr_enabled: Whether to enable OCR for scanned documents\n            ocr_server_url: URL of HTTP OCR server (uses Tesseract if not provided)\n            ocr_language: Language code for OCR\n            num_workers: Number of pages to OCR in parallel (defaults to CPU cores - 1)\n            max_pages: Maximum number of pages to parse per file\n            dpi: DPI for rendering\n            precise_bounding_box: Whether to compute precise bounding boxes\n            recursive: Whether to recursively search subdirectories\n            extension_filter: Only process files with this extension (e.g., \".pdf\")\n            password: Password for encrypted/protected documents (applied to all files)\n            timeout: Timeout in seconds for the entire batch\n\n        Returns:\n            BatchResult with output directory path\n\n        Raises:\n            FileNotFoundError: If the input directory doesn't exist\n            TimeoutError: If the batch operation times out\n        \"\"\"\n        input_dir, output_dir, output_format = self._extract_batch_params(\n            input_dir, output_dir, output_format\n        )\n\n        # Build command\n        cmd = self._prepare_command(\n            \"batch-parse\",\n            str(input_dir.absolute()),\n            str(output_dir.absolute()),\n            output_format=output_format,\n            ocr_enabled=ocr_enabled,\n            ocr_server_url=ocr_server_url,\n            ocr_language=ocr_language,\n            num_workers=num_workers,\n            max_pages=max_pages,\n            dpi=dpi,\n            precise_bounding_box=precise_bounding_box,\n            recursive=recursive,\n            extension_filter=extension_filter,\n            password=password,\n        )\n\n        try:\n            process = await asyncio.subprocess.create_subprocess_exec(\n                cmd[0],\n                *cmd[1:],\n            )\n            await asyncio.wait_for(process.wait(), timeout=timeout)\n\n            return BatchResult(output_dir=str(output_dir))\n\n        except TimeoutError:\n            raise TimeoutError(f\"Batch parsing timed out after {timeout} seconds\")\n\n    def screenshot(\n        self,\n        file_path: Union[str, Path],\n        output_dir: Optional[Union[str, Path]] = None,\n        *,\n        target_pages: Optional[str] = None,\n        dpi: int = 150,\n        image_format: Union[ImageFormat, str] = ImageFormat.PNG,\n        password: Optional[str] = None,\n        load_bytes: bool = False,\n        timeout: Optional[float] = None,\n    ) -> ScreenshotBatchResult:\n        \"\"\"\n        Generate screenshots of document pages.\n\n        Args:\n            file_path: Path to the document file\n            output_dir: Directory to save screenshots (uses temp dir if not provided)\n            target_pages: Specific pages to screenshot (e.g., \"1,3,5\" or \"1-5\")\n            dpi: DPI for rendering\n            image_format: Image format (\"png\" or \"jpg\")\n            password: Password for encrypted/protected documents\n            load_bytes: If True, load image bytes into ScreenshotResult objects\n            timeout: Timeout in seconds\n\n        Returns:\n            ScreenshotBatchResult containing paths to generated screenshots\n\n        Raises:\n            FileNotFoundError: If the file doesn't exist\n            TimeoutError: If the operation times out\n        \"\"\"\n        file_path, image_format, output_dir = self._extract_screenshot_params(\n            file_path, image_format, output_dir\n        )\n\n        # Build command\n        cmd = self._prepare_command(\n            \"screenshot\",\n            str(file_path.absolute()),\n            \"-o\",\n            str(output_dir.absolute()),\n            \"--format\",\n            image_format.value,\n            \"--dpi\",\n            str(dpi),\n            \"-q\",\n        )\n\n        if target_pages:\n            cmd.extend([\"--target-pages\", target_pages])\n\n        if password:\n            cmd.extend([\"--password\", password])\n\n        try:\n            result = subprocess.run(\n                cmd,\n                capture_output=True,\n                text=True,\n                timeout=timeout,\n                check=False,\n            )\n\n            return self._get_screenshot_result(\n                result.returncode,\n                result.stderr,\n                output_dir,\n                image_format,\n                load_bytes,\n            )\n\n        except subprocess.TimeoutExpired:\n            raise TimeoutError(\n                f\"Screenshot generation timed out after {timeout} seconds\"\n            )\n\n    async def screenshot_async(\n        self,\n        file_path: Union[str, Path],\n        output_dir: Optional[Union[str, Path]] = None,\n        *,\n        target_pages: Optional[str] = None,\n        dpi: int = 150,\n        image_format: Union[ImageFormat, str] = ImageFormat.PNG,\n        password: Optional[str] = None,\n        load_bytes: bool = False,\n        timeout: Optional[float] = None,\n    ) -> ScreenshotBatchResult:\n        \"\"\"\n        Generate screenshots of document pages (asynchronously).\n\n        Args:\n            file_path: Path to the document file\n            output_dir: Directory to save screenshots (uses temp dir if not provided)\n            target_pages: Specific pages to screenshot (e.g., \"1,3,5\" or \"1-5\")\n            dpi: DPI for rendering\n            image_format: Image format (\"png\" or \"jpg\")\n            password: Password for encrypted/protected documents\n            load_bytes: If True, load image bytes into ScreenshotResult objects\n            timeout: Timeout in seconds\n\n        Returns:\n            ScreenshotBatchResult containing paths to generated screenshots\n\n        Raises:\n            FileNotFoundError: If the file doesn't exist\n            TimeoutError: If the operation times out\n        \"\"\"\n        file_path, image_format, output_dir = self._extract_screenshot_params(\n            file_path, image_format, output_dir\n        )\n\n        # Build command\n        cmd = self._prepare_command(\n            \"screenshot\",\n            str(file_path.absolute()),\n            \"-o\",\n            str(output_dir.absolute()),\n            \"--format\",\n            image_format.value,\n            \"--dpi\",\n            str(dpi),\n            \"-q\",\n        )\n\n        if target_pages:\n            cmd.extend([\"--target-pages\", target_pages])\n\n        if password:\n            cmd.extend([\"--password\", password])\n\n        try:\n            process = await asyncio.subprocess.create_subprocess_exec(cmd[0], *cmd[1:])\n\n            _, stderr = await asyncio.wait_for(process.communicate(), timeout=timeout)\n\n            return self._get_screenshot_result(\n                cast(int, process.returncode),\n                (stderr or b\"\").decode(\"utf-8\"),\n                output_dir,\n                image_format,\n                load_bytes,\n            )\n\n        except TimeoutError:\n            raise TimeoutError(\n                f\"Screenshot generation timed out after {timeout} seconds\"\n            )\n\n    def __repr__(self) -> str:\n        return f\"LiteParse(cli_path={self._cli_path!r})\"\n"
  },
  {
    "path": "packages/python/liteparse/py.typed",
    "content": ""
  },
  {
    "path": "packages/python/liteparse/types.py",
    "content": "from __future__ import annotations\n\nfrom dataclasses import dataclass, field\nfrom enum import Enum\nfrom typing import List, Optional, Any, Dict, Iterator\n\n\nclass OutputFormat(str, Enum):\n    \"\"\"Output format options.\"\"\"\n    JSON = \"json\"\n    TEXT = \"text\"\n\n\nclass ImageFormat(str, Enum):\n    \"\"\"Image format options for screenshots.\"\"\"\n    PNG = \"png\"\n    JPG = \"jpg\"\n\n\n@dataclass\nclass BoundingBox:\n    \"\"\"Bounding box coordinates.\"\"\"\n    x1: float\n    y1: float\n    x2: float\n    y2: float\n\n\n@dataclass\nclass TextItem:\n    \"\"\"Individual text item extracted from a document.\"\"\"\n    text: str\n    x: float\n    y: float\n    width: float\n    height: float\n    confidence: Optional[float] = None\n    fontName: Optional[str] = None\n    fontSize: Optional[float] = None\n\n\n@dataclass\nclass ParsedPage:\n    \"\"\"A parsed page from a document.\"\"\"\n    pageNum: int\n    width: float\n    height: float\n    text: str\n    textItems: List[TextItem] = field(default_factory=list)\n    boundingBoxes: List[BoundingBox] = field(default_factory=list)\n\n\n@dataclass\nclass ParseResult:\n    \"\"\"Result of parsing a document.\"\"\"\n    pages: List[ParsedPage]\n    text: str\n    json: Optional[Dict[str, Any]] = None\n\n    @property\n    def num_pages(self) -> int:\n        \"\"\"Number of pages in the document.\"\"\"\n        return len(self.pages)\n\n    def get_page(self, page_num: int) -> Optional[ParsedPage]:\n        \"\"\"Get a specific page by number (1-indexed).\"\"\"\n        for page in self.pages:\n            if page.pageNum == page_num:\n                return page\n        return None\n\n\n@dataclass\nclass BatchResult:\n    \"\"\"Result of batch parsing.\"\"\"\n    output_dir: str\n\n\n@dataclass\nclass ScreenshotResult:\n    \"\"\"Result of a single page screenshot.\"\"\"\n    page_num: int\n    image_path: str\n    image_bytes: Optional[bytes] = None\n\n\n@dataclass\nclass ScreenshotBatchResult:\n    \"\"\"Result of screenshot operation.\"\"\"\n    screenshots: List[ScreenshotResult]\n    output_dir: str\n\n    def __len__(self) -> int:\n        return len(self.screenshots)\n\n    def __iter__(self) -> Iterator[ScreenshotResult]:\n        return iter(self.screenshots)\n\n    def get_page(self, page_num: int) -> Optional[ScreenshotResult]:\n        \"\"\"Get screenshot for a specific page.\"\"\"\n        for s in self.screenshots:\n            if s.page_num == page_num:\n                return s\n        return None\n\n\nclass ParseError(Exception):\n    \"\"\"Exception raised when parsing fails.\"\"\"\n    def __init__(self, message: str, stderr: Optional[str] = None):\n        super().__init__(message)\n        self.stderr = stderr\n\n\nclass CLINotFoundError(Exception):\n    \"\"\"Exception raised when the liteparse CLI is not found.\"\"\"\n    pass\n"
  },
  {
    "path": "packages/python/pyproject.toml",
    "content": "[build-system]\nrequires = [\"hatchling\"]\nbuild-backend = \"hatchling.build\"\n\n[project]\nname = \"liteparse\"\nversion = \"1.2.1\"\ndescription = \"Python wrapper for LiteParse - fast, lightweight PDF and document parsing\"\nreadme = \"README.md\"\nlicense = \"MIT\"\nrequires-python = \">=3.10\"\nauthors = [\n    { name = \"Logan Markewich\", email = \"logan@runllama.ai\" },\n]\nkeywords = [\"pdf\", \"parsing\", \"ocr\", \"document\", \"text-extraction\"]\nclassifiers = [\n    \"Development Status :: 4 - Beta\",\n    \"Intended Audience :: Developers\",\n    \"License :: OSI Approved :: MIT License\",\n    \"Programming Language :: Python :: 3\",\n    \"Programming Language :: Python :: 3.10\",\n    \"Programming Language :: Python :: 3.11\",\n    \"Programming Language :: Python :: 3.12\",\n    \"Programming Language :: Python :: 3.13\",\n    \"Programming Language :: Python :: 3.14\",\n    \"Topic :: Text Processing\",\n    \"Topic :: Scientific/Engineering :: Information Analysis\",\n    \"Typing :: Typed\",\n]\n\n[project.urls]\nHomepage = \"https://github.com/run-llama/liteparse\"\nDocumentation = \"https://github.com/run-llama/liteparse#readme\"\nRepository = \"https://github.com/run-llama/liteparse\"\n\n[project.optional-dependencies]\ndev = [\n    \"pytest>=7.0\",\n    \"pytest-asyncio>=0.21\",\n    \"mypy>=1.0\",\n]\n\n[tool.hatch.build.targets.wheel]\npackages = [\"liteparse\"]\n\n[tool.mypy]\npython_version = \"3.10\"\nstrict = true\nwarn_return_any = true\nwarn_unused_ignores = true\n"
  },
  {
    "path": "packages/python/tests/__init__.py",
    "content": ""
  },
  {
    "path": "packages/python/tests/conftest.py",
    "content": "\"\"\"Shared fixtures for e2e tests.\"\"\"\n\nfrom pathlib import Path\n\nimport pytest\n\nfrom liteparse import LiteParse\n\n# Resolve test-docs relative to the repo root\nREPO_ROOT = Path(__file__).resolve().parents[3]\nTEST_DOCS = REPO_ROOT / \"test-docs\"\nEXPECTED_DATASET = REPO_ROOT / \"expected-dataset\" / \"data\"\n\n\n@pytest.fixture\ndef parser() -> LiteParse:\n    \"\"\"LiteParse instance (auto-detects CLI).\"\"\"\n    return LiteParse()\n\n\n@pytest.fixture\ndef invoice_pdf() -> Path:\n    \"\"\"Path to a small single-page invoice PDF.\"\"\"\n    p = TEST_DOCS / \"invoice.pdf\"\n    if not p.exists():\n        pytest.skip(f\"Test document not found: {p}\")\n    return p\n\n\n@pytest.fixture\ndef two_page_pdf() -> Path:\n    \"\"\"Path to a 2-page PDF.\"\"\"\n    p = EXPECTED_DATASET / \"2pages.pdf\"\n    if not p.exists():\n        pytest.skip(f\"Test document not found: {p}\")\n    return p\n\n\n@pytest.fixture\ndef empty_pdf() -> Path:\n    \"\"\"Path to an empty PDF.\"\"\"\n    p = EXPECTED_DATASET / \"empty.pdf\"\n    if not p.exists():\n        pytest.skip(f\"Test document not found: {p}\")\n    return p\n"
  },
  {
    "path": "packages/python/tests/test_batch_e2e.py",
    "content": "\"\"\"E2E tests for LiteParse.batch_parse() — validates Python types match CLI output.\"\"\"\n\nimport tempfile\nfrom pathlib import Path\n\nimport pytest\n\nfrom liteparse import (\n    BatchResult,\n    LiteParse,\n    OutputFormat,\n)\n\n\nclass TestBatchParseBasic:\n    \"\"\"Basic batch parsing functionality.\"\"\"\n\n    def test_batch_parse_returns_batch_result(\n        self, parser: LiteParse, invoice_pdf: Path\n    ):\n        input_dir = invoice_pdf.parent\n        with tempfile.TemporaryDirectory() as tmpdir:\n            result = parser.batch_parse(\n                input_dir,\n                tmpdir,\n                ocr_enabled=False,\n                extension_filter=\".pdf\",\n            )\n            assert isinstance(result, BatchResult)\n            assert result.output_dir == tmpdir\n\n    def test_batch_parse_creates_output_files(\n        self, parser: LiteParse, invoice_pdf: Path\n    ):\n        input_dir = invoice_pdf.parent\n        with tempfile.TemporaryDirectory() as tmpdir:\n            parser.batch_parse(\n                input_dir,\n                tmpdir,\n                output_format=OutputFormat.TEXT,\n                ocr_enabled=False,\n                extension_filter=\".pdf\",\n            )\n            output_files = list(Path(tmpdir).rglob(\"*\"))\n            # Should have produced at least one output file\n            assert len(output_files) > 0\n\n    def test_batch_parse_json_format(self, parser: LiteParse, invoice_pdf: Path):\n        input_dir = invoice_pdf.parent\n        with tempfile.TemporaryDirectory() as tmpdir:\n            parser.batch_parse(\n                input_dir,\n                tmpdir,\n                output_format=\"json\",\n                ocr_enabled=False,\n                extension_filter=\".pdf\",\n            )\n            json_files = list(Path(tmpdir).rglob(\"*.json\"))\n            assert len(json_files) > 0\n\n    @pytest.mark.asyncio\n    async def test_batch_parse_async(self, parser: LiteParse, invoice_pdf: Path):\n        input_dir = invoice_pdf.parent\n        with tempfile.TemporaryDirectory() as tmpdir:\n            result = await parser.batch_parse_async(\n                input_dir,\n                tmpdir,\n                output_format=\"json\",\n                ocr_enabled=False,\n                extension_filter=\".pdf\",\n            )\n            assert isinstance(result, BatchResult)\n            assert result.output_dir == tmpdir\n\n\nclass TestBatchParseErrors:\n    \"\"\"Test error handling.\"\"\"\n\n    def test_input_dir_not_found(self, parser: LiteParse):\n        with tempfile.TemporaryDirectory() as tmpdir:\n            with pytest.raises(FileNotFoundError):\n                parser.batch_parse(\"/nonexistent/dir\", tmpdir)\n\n    @pytest.mark.asyncio\n    async def test_input_dir_not_found_async(self, parser: LiteParse):\n        with tempfile.TemporaryDirectory() as tmpdir:\n            with pytest.raises(FileNotFoundError):\n                await parser.batch_parse_async(\"/nonexistent/dir\", tmpdir)\n"
  },
  {
    "path": "packages/python/tests/test_parse_e2e.py",
    "content": "\"\"\"E2E tests for LiteParse.parse() — validates Python types match CLI output.\"\"\"\n\nfrom pathlib import Path\n\nimport pytest\n\nfrom liteparse import (\n    BoundingBox,\n    LiteParse,\n    ParsedPage,\n    ParseError,\n    ParseResult,\n    TextItem,\n)\n\n\nclass TestParseBasic:\n    \"\"\"Basic parse functionality and output structure.\"\"\"\n\n    def test_parse_returns_parse_result(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.parse(invoice_pdf, ocr_enabled=False)\n        assert isinstance(result, ParseResult)\n\n    def test_parse_result_has_pages(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.parse(invoice_pdf, ocr_enabled=False)\n        assert len(result.pages) > 0\n        assert result.num_pages == len(result.pages)\n\n    def test_parse_result_has_text(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.parse(invoice_pdf, ocr_enabled=False)\n        assert isinstance(result.text, str)\n        assert len(result.text) > 0\n\n    def test_parse_result_has_json(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.parse(invoice_pdf, ocr_enabled=False)\n        assert result.json is not None\n        assert \"pages\" in result.json\n\n    def test_parse_bytest_input(self, parser: LiteParse, invoice_pdf: Path):\n        file_bytes = invoice_pdf.read_bytes()\n        result = parser.parse(file_bytes)\n        assert result.json is not None\n        assert \"pages\" in result.json\n\n    @pytest.mark.asyncio\n    async def test_parse_async(self, parser: LiteParse, invoice_pdf: Path):\n        result = await parser.parse_async(invoice_pdf)\n        assert result.json is not None\n        assert \"pages\" in result.json\n\n    @pytest.mark.asyncio\n    async def test_parse_async_bytes_input(self, parser: LiteParse, invoice_pdf: Path):\n        file_bytes = invoice_pdf.read_bytes()\n        result = await parser.parse_async(file_bytes)\n        assert result.json is not None\n        assert \"pages\" in result.json\n\n\nclass TestParsedPageStructure:\n    \"\"\"Validate ParsedPage fields match CLI output.\"\"\"\n\n    def test_page_fields(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.parse(invoice_pdf, ocr_enabled=False)\n        page = result.pages[0]\n        assert isinstance(page, ParsedPage)\n        assert isinstance(page.pageNum, int)\n        assert page.pageNum >= 1\n        assert isinstance(page.width, (int, float))\n        assert isinstance(page.height, (int, float))\n        assert page.width > 0\n        assert page.height > 0\n        assert isinstance(page.text, str)\n\n    def test_page_has_text_items(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.parse(invoice_pdf, ocr_enabled=False)\n        page = result.pages[0]\n        assert len(page.textItems) > 0\n\n    def test_text_item_fields(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.parse(invoice_pdf, ocr_enabled=False)\n        item = result.pages[0].textItems[0]\n        assert isinstance(item, TextItem)\n        assert isinstance(item.text, str)\n        assert isinstance(item.x, (int, float))\n        assert isinstance(item.y, (int, float))\n        assert isinstance(item.width, (int, float))\n        assert isinstance(item.height, (int, float))\n        # fontName and fontSize may be None or present\n        if item.fontName is not None:\n            assert isinstance(item.fontName, str)\n        if item.fontSize is not None:\n            assert isinstance(item.fontSize, (int, float))\n\n    def test_bounding_box_fields(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.parse(invoice_pdf, ocr_enabled=False, precise_bounding_box=True)\n        page = result.pages[0]\n        assert len(page.boundingBoxes) > 0\n        bbox = page.boundingBoxes[0]\n        assert isinstance(bbox, BoundingBox)\n        assert isinstance(bbox.x1, (int, float))\n        assert isinstance(bbox.y1, (int, float))\n        assert isinstance(bbox.x2, (int, float))\n        assert isinstance(bbox.y2, (int, float))\n\n\nclass TestParseOptions:\n    \"\"\"Test that CLI options are correctly forwarded.\"\"\"\n\n    def test_target_pages(self, parser: LiteParse, invoice_pdf: Path):\n        # invoice.pdf has 2 pages — parse only page 1\n        result = parser.parse(invoice_pdf, ocr_enabled=False, target_pages=\"1\")\n        assert result.num_pages == 1\n        assert result.pages[0].pageNum == 1\n\n    def test_max_pages(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.parse(invoice_pdf, ocr_enabled=False, max_pages=1)\n        assert result.num_pages == 1\n\n    def test_no_precise_bbox(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.parse(\n            invoice_pdf, ocr_enabled=False, precise_bounding_box=False\n        )\n        assert isinstance(result, ParseResult)\n        # With no precise bbox, boundingBoxes should be empty\n        for page in result.pages:\n            assert len(page.boundingBoxes) == 0\n\n    def test_get_page_helper(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.parse(invoice_pdf, ocr_enabled=False)\n        page1 = result.get_page(1)\n        assert page1 is not None\n        assert page1.pageNum == 1\n        assert result.get_page(999) is None\n\n    def test_multi_page_text_joined(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.parse(invoice_pdf, ocr_enabled=False)\n        assert result.num_pages == 2\n        # result.text should be the join of all page texts\n        expected = \"\\n\\n\".join(p.text for p in result.pages)\n        assert result.text == expected\n\n\nclass TestParseErrors:\n    \"\"\"Test error handling.\"\"\"\n\n    def test_file_not_found(self, parser: LiteParse):\n        with pytest.raises(FileNotFoundError):\n            parser.parse(\"/nonexistent/file.pdf\")\n\n    def test_cli_not_found(self):\n        parser = LiteParse(cli_path=\"/nonexistent/liteparse\")\n        # subprocess raises FileNotFoundError when the binary doesn't exist\n        with pytest.raises((ParseError, FileNotFoundError, OSError)):\n            parser.parse(Path(__file__))  # any existing file\n\n    def test_timeout(self, parser: LiteParse, invoice_pdf: Path):\n        # Extremely short timeout should fail\n        with pytest.raises(TimeoutError):\n            parser.parse(invoice_pdf, timeout=0.001)\n\n    @pytest.mark.asyncio\n    async def test_file_not_found_async(self, parser: LiteParse):\n        with pytest.raises(FileNotFoundError):\n            await parser.parse_async(\"/nonexistent/file.pdf\")\n\n    @pytest.mark.asyncio\n    async def test_cli_not_found_async(self):\n        parser = LiteParse(cli_path=\"/nonexistent/liteparse\")\n        # subprocess raises FileNotFoundError when the binary doesn't exist\n        with pytest.raises((ParseError, FileNotFoundError, OSError)):\n            parser.parse(Path(__file__))  # any existing file\n\n    @pytest.mark.asyncio\n    async def test_timeout_async(self, parser: LiteParse, invoice_pdf: Path):\n        with pytest.raises(TimeoutError):\n            await parser.parse_async(invoice_pdf, timeout=0.001)\n"
  },
  {
    "path": "packages/python/tests/test_screenshot_e2e.py",
    "content": "\"\"\"E2E tests for LiteParse.screenshot() — validates Python types match CLI output.\"\"\"\n\nimport tempfile\nfrom pathlib import Path\n\nimport pytest\n\nfrom liteparse import (\n    ImageFormat,\n    LiteParse,\n    ScreenshotBatchResult,\n    ScreenshotResult,\n)\n\n\nclass TestScreenshotBasic:\n    \"\"\"Basic screenshot functionality.\"\"\"\n\n    def test_screenshot_returns_batch_result(\n        self, parser: LiteParse, invoice_pdf: Path\n    ):\n        result = parser.screenshot(invoice_pdf)\n        assert isinstance(result, ScreenshotBatchResult)\n\n    def test_screenshot_has_screenshots(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.screenshot(invoice_pdf)\n        assert len(result) > 0\n        assert len(result.screenshots) > 0\n\n    def test_screenshot_result_fields(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.screenshot(invoice_pdf)\n        ss = result.screenshots[0]\n        assert isinstance(ss, ScreenshotResult)\n        assert isinstance(ss.page_num, int)\n        assert ss.page_num >= 1\n        assert isinstance(ss.image_path, str)\n        assert Path(ss.image_path).exists()\n\n    def test_screenshot_output_dir(self, parser: LiteParse, invoice_pdf: Path):\n        with tempfile.TemporaryDirectory() as tmpdir:\n            result = parser.screenshot(invoice_pdf, output_dir=tmpdir)\n            assert result.output_dir == tmpdir\n            # Files should be in the specified directory\n            for ss in result.screenshots:\n                assert ss.image_path.startswith(tmpdir)\n\n    def test_screenshot_png_format(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.screenshot(invoice_pdf, image_format=ImageFormat.PNG)\n        for ss in result.screenshots:\n            assert ss.image_path.endswith(\".png\")\n\n    def test_screenshot_jpg_format(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.screenshot(invoice_pdf, image_format=\"jpg\")\n        for ss in result.screenshots:\n            assert ss.image_path.endswith(\".jpg\")\n\n    @pytest.mark.asyncio\n    async def test_screensho_async_basic(self, parser: LiteParse, invoice_pdf: Path):\n        result = await parser.screenshot_async(invoice_pdf, image_format=\"png\")\n        assert isinstance(result, ScreenshotBatchResult)\n        assert len(result.screenshots) > 0\n\n\nclass TestScreenshotOptions:\n    \"\"\"Test screenshot options are forwarded correctly.\"\"\"\n\n    def test_target_pages(self, parser: LiteParse, invoice_pdf: Path):\n        # invoice.pdf has 2 pages — screenshot only page 1\n        result = parser.screenshot(invoice_pdf, target_pages=\"1\")\n        assert len(result) == 1\n        assert result.screenshots[0].page_num == 1\n\n    def test_load_bytes(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.screenshot(invoice_pdf, load_bytes=True)\n        for ss in result.screenshots:\n            assert ss.image_bytes is not None\n            assert len(ss.image_bytes) > 0\n\n    def test_no_load_bytes(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.screenshot(invoice_pdf, load_bytes=False)\n        for ss in result.screenshots:\n            assert ss.image_bytes is None\n\n    def test_get_page_helper(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.screenshot(invoice_pdf)\n        page1 = result.get_page(1)\n        assert page1 is not None\n        assert page1.page_num == 1\n        assert result.get_page(999) is None\n\n    def test_iterable(self, parser: LiteParse, invoice_pdf: Path):\n        result = parser.screenshot(invoice_pdf)\n        pages = list(result)\n        assert len(pages) == len(result)\n\n\nclass TestScreenshotErrors:\n    \"\"\"Test error handling.\"\"\"\n\n    def test_file_not_found(self, parser: LiteParse):\n        with pytest.raises(FileNotFoundError):\n            parser.screenshot(\"/nonexistent/file.pdf\")\n"
  },
  {
    "path": "scripts/compare-dataset.ts",
    "content": "/**\n * Compares current liteparse output against a baseline dataset\n *\n * Usage:\n *   npx tsx scripts/compare-dataset.ts [dataset-dir]\n *\n * The dataset should be created using create-dataset.ts and contains:\n *   - data/: The original document files\n *   - metadata.jsonl: Expected outputs for each document/page\n *\n * Exit codes:\n *   0 - No changes detected\n *   1 - Changes detected (requires approval)\n *   2 - Error occurred\n *\n * For CI/CD, this script can be run to detect if a PR changes output.\n * If changes are detected, the PR should require manual approval.\n */\n\nimport { LiteParse } from \"../src/lib.js\";\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nconst DEFAULT_DATASET_DIR = path.join(import.meta.dirname, \"..\", \"dataset\");\n\ninterface DatasetRow {\n  file_name: string;\n  document: string;\n  page: number;\n  output_text: string;\n  output_json: object;\n}\n\ninterface DiffResult {\n  document: string;\n  page: number;\n  type: \"added\" | \"removed\" | \"changed\";\n  expected?: string;\n  actual?: string;\n  diff?: string;\n}\n\nasync function loadDataset(datasetDir: string): Promise<Map<string, DatasetRow>> {\n  const metadataPath = path.join(datasetDir, \"metadata.jsonl\");\n  const content = await fs.readFile(metadataPath, \"utf-8\");\n  const rows = content\n    .split(\"\\n\")\n    .filter((line) => line.trim())\n    .map((line) => JSON.parse(line) as DatasetRow);\n\n  const map = new Map<string, DatasetRow>();\n  for (const row of rows) {\n    const key = `${row.document}:${row.page}`;\n    map.set(key, row);\n  }\n\n  return map;\n}\n\n/**\n * Normalize text for comparison - handles cross-platform LibreOffice differences.\n * Collapses whitespace runs to single space and trims each line.\n */\nfunction normalizeForComparison(text: string): string {\n  return text\n    .split(\"\\n\")\n    .map((line) => line.replace(/\\s+/g, \" \").trim())\n    .filter((line) => line.length > 0)\n    .join(\"\\n\");\n}\n\ninterface DiffHunk {\n  startLine: number;\n  endLine: number;\n}\n\nfunction computeTextDiff(expected: string, actual: string, maxHunks = 5, contextLines = 1): string {\n  const expectedLines = expected.split(\"\\n\");\n  const actualLines = actual.split(\"\\n\");\n\n  // Find all changed line indices\n  const maxLines = Math.max(expectedLines.length, actualLines.length);\n  const changedIndices: number[] = [];\n\n  for (let i = 0; i < maxLines; i++) {\n    const exp = expectedLines[i] ?? \"\";\n    const act = actualLines[i] ?? \"\";\n    if (exp !== act) {\n      changedIndices.push(i);\n    }\n  }\n\n  if (changedIndices.length === 0) {\n    return \"\";\n  }\n\n  // Group consecutive changes into hunks (with context gap tolerance)\n  const hunks: DiffHunk[] = [];\n  let currentHunk: DiffHunk | null = null;\n\n  for (const idx of changedIndices) {\n    // Start new hunk if this change is far from the previous one\n    // (more than 2*contextLines apart, so hunks don't overlap)\n    if (!currentHunk || idx > currentHunk.endLine + 2 * contextLines + 1) {\n      if (currentHunk) {\n        hunks.push(currentHunk);\n      }\n      currentHunk = {\n        startLine: idx,\n        endLine: idx,\n      };\n    } else {\n      currentHunk.endLine = idx;\n    }\n  }\n  if (currentHunk) {\n    hunks.push(currentHunk);\n  }\n\n  // Build output for each hunk (limited to maxHunks)\n  const output: string[] = [];\n  const displayHunks = hunks.slice(0, maxHunks);\n\n  for (const hunk of displayHunks) {\n    // Expand hunk range to include context\n    const contextStart = Math.max(0, hunk.startLine - contextLines);\n    const contextEnd = Math.min(maxLines - 1, hunk.endLine + contextLines);\n\n    // Format hunk header\n    const lineRange = hunk.startLine === hunk.endLine\n      ? `line ${hunk.startLine + 1}`\n      : `lines ${hunk.startLine + 1}-${hunk.endLine + 1}`;\n    output.push(`@@ ${lineRange} @@`);\n\n    // Collect context before, removed lines, added lines, and context after\n    const contextBefore: string[] = [];\n    const removedLines: string[] = [];\n    const addedLines: string[] = [];\n    const contextAfter: string[] = [];\n\n    for (let i = contextStart; i <= contextEnd; i++) {\n      const exp = expectedLines[i] ?? \"\";\n      const act = actualLines[i] ?? \"\";\n      const isBeforeChanges = i < hunk.startLine;\n      const isAfterChanges = i > hunk.endLine;\n\n      if (exp === act) {\n        // Context line (unchanged)\n        if (isBeforeChanges) {\n          contextBefore.push(`  ${i + 1}: ${exp}`);\n        } else if (isAfterChanges) {\n          contextAfter.push(`  ${i + 1}: ${exp}`);\n        }\n      } else {\n        // Changed line - collect separately\n        if (exp) {\n          removedLines.push(`- ${i + 1}: ${exp}`);\n        }\n        if (act) {\n          addedLines.push(`+ ${i + 1}: ${act}`);\n        }\n      }\n    }\n\n    // Output: context before, then all removed, then all added, then context after\n    output.push(...contextBefore);\n    output.push(...removedLines);\n    output.push(...addedLines);\n    output.push(...contextAfter);\n  }\n\n  if (hunks.length > maxHunks) {\n    output.push(`\\n... (${hunks.length - maxHunks} more change groups)`);\n  }\n\n  return output.join(\"\\n\");\n}\n\nasync function getCurrentOutput(\n  filePath: string\n): Promise<Map<number, { text: string; json: object }>> {\n  const parser = new LiteParse({\n    outputFormat: \"json\",\n    ocrEnabled: false,\n    preciseBoundingBox: true,\n  });\n\n  const result = await parser.parse(filePath, true);\n  const outputs = new Map<number, { text: string; json: object }>();\n\n  if (result.pages.length === 0 && result.text) {\n    // Text-only result\n    outputs.set(1, { text: result.text, json: { text: result.text } });\n  } else {\n    for (const page of result.pages) {\n      const jsonPage = result.json?.pages.find((p) => p.page === page.pageNum);\n      outputs.set(page.pageNum, {\n        text: page.text,\n        json: jsonPage || { page: page.pageNum, text: page.text },\n      });\n    }\n  }\n\n  return outputs;\n}\n\nasync function main() {\n  const datasetDir = process.argv[2] || DEFAULT_DATASET_DIR;\n  const documentsDir = path.join(datasetDir, \"data\");\n\n  console.log(\"LiteParse Dataset Comparison\");\n  console.log(\"============================\");\n  console.log(`Dataset: ${datasetDir}`);\n  console.log(`Documents: ${documentsDir}`);\n  console.log();\n\n  // Load expected dataset\n  let expected: Map<string, DatasetRow>;\n  try {\n    expected = await loadDataset(datasetDir);\n    console.log(`Loaded ${expected.size} expected entries\\n`);\n\n    if (expected.size === 0) {\n      console.error(\"ERROR: metadata.jsonl is empty — dataset has no entries to compare against.\");\n      console.error(\"The dataset may need to be regenerated with: npx tsx scripts/create-dataset.ts\");\n      process.exit(2);\n    }\n  } catch (error) {\n    console.error(`Failed to load dataset: ${error}`);\n    process.exit(2);\n  }\n\n  const diffs: DiffResult[] = [];\n  const processedKeys = new Set<string>();\n\n  // Group expected entries by document\n  const docEntries = new Map<string, DatasetRow[]>();\n  for (const row of expected.values()) {\n    const existing = docEntries.get(row.document) || [];\n    existing.push(row);\n    docEntries.set(row.document, existing);\n  }\n\n  // Process each document\n  for (const [document, rows] of docEntries) {\n    const filePath = path.join(documentsDir, document);\n\n    // Check if file still exists\n    try {\n      await fs.access(filePath);\n    } catch {\n      // File removed\n      for (const row of rows) {\n        const key = `${row.document}:${row.page}`;\n        processedKeys.add(key);\n        diffs.push({\n          document: row.document,\n          page: row.page,\n          type: \"removed\",\n          expected: row.output_text,\n        });\n      }\n      continue;\n    }\n\n    console.log(`Checking: ${document}`);\n\n    try {\n      const currentOutputs = await getCurrentOutput(filePath);\n\n      // Compare each page\n      for (const row of rows) {\n        const key = `${row.document}:${row.page}`;\n        processedKeys.add(key);\n\n        const current = currentOutputs.get(row.page);\n        if (!current) {\n          diffs.push({\n            document: row.document,\n            page: row.page,\n            type: \"removed\",\n            expected: row.output_text,\n          });\n          continue;\n        }\n\n        // Compare text output\n        // For non-PDF files (PPTX, DOCX, etc.), normalize whitespace because\n        // LibreOffice conversion produces different spacing across platforms.\n        // For PDFs, use strict comparison since they're parsed directly.\n        const expectedText = row.output_text.trim();\n        const actualText = current.text.trim();\n        const isPdf = row.document.toLowerCase().endsWith(\".pdf\");\n\n        const expectedCompare = isPdf ? expectedText : normalizeForComparison(expectedText);\n        const actualCompare = isPdf ? actualText : normalizeForComparison(actualText);\n\n        if (expectedCompare !== actualCompare) {\n          diffs.push({\n            document: row.document,\n            page: row.page,\n            type: \"changed\",\n            expected: expectedText,\n            actual: actualText,\n            diff: computeTextDiff(expectedText, actualText),\n          });\n        }\n\n        currentOutputs.delete(row.page);\n      }\n\n      // Check for new pages\n      for (const [pageNum, output] of currentOutputs) {\n        diffs.push({\n          document,\n          page: pageNum,\n          type: \"added\",\n          actual: output.text,\n        });\n      }\n    } catch (error) {\n      console.error(`  ERROR: ${error instanceof Error ? error.message : error}`);\n      // Check if it was an expected error\n      const errorRow = rows.find(\n        (r) => (r.output_json as { error?: boolean }).error === true\n      );\n      if (!errorRow) {\n        diffs.push({\n          document,\n          page: 0,\n          type: \"changed\",\n          expected: \"successful parse\",\n          actual: `error: ${error instanceof Error ? error.message : error}`,\n        });\n      }\n      for (const row of rows) {\n        processedKeys.add(`${row.document}:${row.page}`);\n      }\n    }\n  }\n\n  // Report results\n  console.log();\n  console.log(\"Results\");\n  console.log(\"-------\");\n\n  if (diffs.length === 0) {\n    console.log(\"✓ No changes detected\");\n    process.exit(0);\n  }\n\n  console.log(`✗ ${diffs.length} change(s) detected:\\n`);\n\n  for (const diff of diffs) {\n    console.log(`[${diff.type.toUpperCase()}] ${diff.document} (page ${diff.page})`);\n    if (diff.diff) {\n      console.log(diff.diff);\n    }\n    console.log();\n  }\n\n  // Output summary for CI\n  console.log(\"---\");\n  console.log(\"SUMMARY:\");\n  console.log(`  Added: ${diffs.filter((d) => d.type === \"added\").length}`);\n  console.log(`  Removed: ${diffs.filter((d) => d.type === \"removed\").length}`);\n  console.log(`  Changed: ${diffs.filter((d) => d.type === \"changed\").length}`);\n  console.log();\n  console.log(\"This PR changes liteparse output and requires manual approval.\");\n\n  process.exit(1);\n}\n\nmain().catch((error) => {\n  console.error(\"Fatal error:\", error);\n  process.exit(2);\n});\n"
  },
  {
    "path": "scripts/compare-outputs.sh",
    "content": "#!/bin/bash\n# Compare dataset outputs and set GitHub Actions output variables\n# Usage: ./compare-outputs.sh <expected-dataset-path>\n\nset -u\n\nEXPECTED_DATASET=\"${1:-expected-dataset}\"\nOUTPUT_FILE=\"comparison-output.txt\"\n\n# Run comparison script\nset +e\nnpx tsx scripts/compare-dataset.ts \"$EXPECTED_DATASET\" > \"$OUTPUT_FILE\" 2>&1\nEXIT_CODE=$?\nset -e\n\ncat \"$OUTPUT_FILE\"\n\nif [ $EXIT_CODE -eq 0 ]; then\n  echo \"has_changes=false\" >> \"$GITHUB_OUTPUT\"\n  echo \"✓ No output changes detected\"\nelif [ $EXIT_CODE -eq 1 ]; then\n  echo \"has_changes=true\" >> \"$GITHUB_OUTPUT\"\n  echo \"⚠ Output changes detected - requires approval\"\nelse\n  echo \"has_changes=error\" >> \"$GITHUB_OUTPUT\"\n  echo \"✗ Error running comparison\"\n  exit 1\nfi\n"
  },
  {
    "path": "scripts/create-dataset.ts",
    "content": "/**\n * Creates a dataset for regression testing\n *\n * Output structure:\n *   dataset/\n *     data/\n *       doc1.pdf\n *       doc2.docx\n *       ...\n *     metadata.jsonl  (each line: {\"file_name\": \"data/doc1.pdf\", \"document\": \"doc1.pdf\", \"page\": 1, \"output_json\": {...}})\n *\n * Usage:\n *   npx tsx scripts/create-dataset.ts [output-dir] [source-docs-dir]\n *\n * Arguments:\n *   output-dir      - Where to write the dataset (default: ./dataset)\n *   source-docs-dir - Where to read source documents from (default: ./e2e-test-docs)\n *\n * The dataset can be used with compare-dataset.ts to detect output changes.\n */\n\nimport { LiteParse } from \"../src/lib.js\";\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\nconst DEFAULT_SOURCE_DIR = path.join(import.meta.dirname, \"..\", \"e2e-test-docs\");\nconst DEFAULT_OUTPUT_DIR = path.join(import.meta.dirname, \"..\", \"dataset\");\n\ninterface DatasetRow {\n  file_name: string;\n  document: string;\n  page: number;\n  output_text: string;\n  output_json: object;\n}\n\nasync function findFiles(dir: string, baseDir: string = dir): Promise<string[]> {\n  const files: string[] = [];\n  const entries = await fs.readdir(dir, { withFileTypes: true });\n\n  for (const entry of entries) {\n    const fullPath = path.join(dir, entry.name);\n\n    if (entry.isDirectory()) {\n      // Recursively search subdirectories\n      const subFiles = await findFiles(fullPath, baseDir);\n      files.push(...subFiles);\n    } else if (entry.isFile()) {\n      files.push(fullPath);\n    }\n  }\n\n  return files;\n}\n\nasync function processFile(filePath: string, baseDocDir: string): Promise<DatasetRow[]> {\n  const relativePath = path.relative(baseDocDir, filePath);\n\n  console.log(`Processing: ${relativePath}`);\n\n  const rows: DatasetRow[] = [];\n\n  try {\n    // Parse the document\n    const parser = new LiteParse({\n      outputFormat: \"json\",\n      ocrEnabled: false, // Disable OCR for deterministic results\n      preciseBoundingBox: true,\n    });\n\n    const result = await parser.parse(filePath, true);\n\n    // For non-PDF files that return text directly (no pages)\n    if (result.pages.length === 0 && result.text) {\n      rows.push({\n        file_name: `data/${relativePath}`,\n        document: relativePath,\n        page: 1,\n        output_text: result.text,\n        output_json: { text: result.text },\n      });\n      console.log(`  -> 1 text entry`);\n      return rows;\n    }\n\n    // Create entries for each page\n    for (const page of result.pages) {\n      const jsonPage = result.json?.pages.find((p) => p.page === page.pageNum);\n      rows.push({\n        file_name: `data/${relativePath}`,\n        document: relativePath,\n        page: page.pageNum,\n        output_text: page.text,\n        output_json: jsonPage || { page: page.pageNum, text: page.text },\n      });\n    }\n\n    console.log(`  -> ${rows.length} pages`);\n  } catch (error) {\n    console.error(`  ERROR: ${error instanceof Error ? error.message : error}`);\n    // Record the error as a dataset entry (blank result)\n    rows.push({\n      file_name: `data/${relativePath}`,\n      document: relativePath,\n      page: 0,\n      output_text: \"\",\n      output_json: {\n        error: true,\n        message: error instanceof Error ? error.message : String(error),\n      },\n    });\n  }\n\n  return rows;\n}\n\nasync function main() {\n  const outputDir = process.argv[2] || DEFAULT_OUTPUT_DIR;\n  const sourceDocsDir = process.argv[3] || DEFAULT_SOURCE_DIR;\n  const documentsDir = path.join(outputDir, \"data\");\n\n  // Check if source is already in the output documents folder (skip copy in this case)\n  const resolvedSource = path.resolve(sourceDocsDir);\n  const resolvedDocuments = path.resolve(documentsDir);\n  const skipCopy = resolvedSource === resolvedDocuments;\n\n  console.log(\"LiteParse Dataset Generator\");\n  console.log(\"===========================\");\n  console.log(`Source: ${sourceDocsDir}`);\n  console.log(`Output: ${outputDir}`);\n  if (skipCopy) {\n    console.log(`(Source is output documents dir - skipping copy)`);\n  }\n  console.log();\n\n  // Create output directories\n  await fs.mkdir(documentsDir, { recursive: true });\n\n  // Find all processable files\n  console.log(\"Finding files...\");\n  const files = await findFiles(sourceDocsDir);\n  console.log(`Found ${files.length} files to process\\n`);\n\n  // Process each file and copy to documents folder (unless source is already there)\n  const allRows: DatasetRow[] = [];\n  const copiedDocs = new Set<string>();\n\n  for (const file of files) {\n    const rows = await processFile(file, sourceDocsDir);\n    allRows.push(...rows);\n\n    // Copy document file to dataset (only once per document, skip if source is output)\n    const relativePath = path.relative(sourceDocsDir, file);\n    if (!skipCopy && !copiedDocs.has(relativePath)) {\n      const destPath = path.join(documentsDir, relativePath);\n      await fs.mkdir(path.dirname(destPath), { recursive: true });\n      await fs.copyFile(file, destPath);\n      copiedDocs.add(relativePath);\n    } else if (skipCopy) {\n      copiedDocs.add(relativePath);\n    }\n  }\n\n  // Validate we actually produced entries\n  if (allRows.length === 0) {\n    console.error(\"\\nERROR: No dataset entries were generated. Check that source documents exist and are parseable.\");\n    process.exit(1);\n  }\n\n  // Write metadata.jsonl\n  const metadataPath = path.join(outputDir, \"metadata.jsonl\");\n  const metadataContent = allRows.map((row) => JSON.stringify(row)).join(\"\\n\");\n  await fs.writeFile(metadataPath, metadataContent);\n\n  console.log();\n  console.log(\"Dataset generation complete!\");\n  console.log(`  Total entries: ${allRows.length}`);\n  console.log(`  Documents copied: ${copiedDocs.size}`);\n  console.log(`  Metadata: ${metadataPath}`);\n  console.log(`  Documents: ${documentsDir}`);\n  console.log();\n  console.log(\"Use compare-dataset.ts to compare future output against this baseline.\");\n}\n\nmain().catch((error) => {\n  console.error(\"Fatal error:\", error);\n  process.exit(1);\n});\n"
  },
  {
    "path": "scripts/generate-api-docs.sh",
    "content": "#!/usr/bin/env bash\n# Generates API reference docs from TypeDoc and outputs a single\n# Starlight-compatible markdown file with frontmatter.\nset -euo pipefail\n\nDOCS_DIR=\"./docs/src/content/docs/liteparse\"\nTMP_DIR=\"${DOCS_DIR}/.api-tmp\"\nOUT_FILE=\"${DOCS_DIR}/api.md\"\n\n# Generate markdown with TypeDoc\nnpx typedoc\n\n# Prepend Starlight frontmatter to the generated README\ncat > \"${OUT_FILE}\" <<'FRONTMATTER'\n---\ntitle: API Reference\ndescription: API reference for the @llamaindex/liteparse TypeScript library.\nsidebar:\n  order: 6\n---\nFRONTMATTER\n\ncat \"${TMP_DIR}/README.md\" >> \"${OUT_FILE}\"\n\n# Clean up temp directory\nrm -rf \"${TMP_DIR}\"\n\necho \"Generated ${OUT_FILE}\"\n"
  },
  {
    "path": "scripts/publish-to-homebrew-repo.sh",
    "content": "#!/bin/bash\n\necho \"Installing homebrew-npm-noob tool\"\nuv tool install --upgrade homebrew-npm-noob\necho \"Setting up repository locally\"\ngit clone https://x-access-token:${GITHUB_TOKEN}@github.com/run-llama/homebrew-liteparse\ncd homebrew-liteparse\nmkdir -p Formula/\necho \"Generating HomeBrew Formula\"\nnoob @llamaindex/liteparse > Formula/llamaindex-liteparse.rb\necho \"Configuring GitHub user\"\ngit config user.email \"github-actions[bot]@users.noreply.github.com\"\ngit config user.name \"github-actions[bot]\"\necho \"Pushing to GitHub\"\ngit add .\ngit commit -m \"Automated HomeBrew Release for liteparse\"\ngit push -u origin main\necho \"Removing local copy\"\ncd ..\nrm -rf homebrew-liteparse\n"
  },
  {
    "path": "scripts/sync-docs-to-developer-hub.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\nDOCS_REPO=\"${1:?Usage: $0 /path/to/developer-hub-repo}\"\nSCRIPT_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\nREPO_ROOT=\"$(cd \"$SCRIPT_DIR/..\" && pwd)\"\n\n# --- Markdown docs ---\nSOURCE_DIR=\"$REPO_ROOT/docs/src/content/docs/liteparse\"\nDEST_DIR=\"$DOCS_REPO/src/content/docs/liteparse\"\n\necho \"=== Syncing markdown docs ===\"\nmkdir -p \"$DEST_DIR\"\n\nrsync -av --delete \\\n  --include='*/' \\\n  --include='*.md' \\\n  --include='*.mdx' \\\n  --include='*.yml' \\\n  --include='*.png' \\\n  --include='*.jpg' \\\n  --include='*.jpeg' \\\n  --include='*.svg' \\\n  --exclude='*' \\\n  \"$SOURCE_DIR/\" \"$DEST_DIR/\"\n\necho \"Docs sync complete.\"\n"
  },
  {
    "path": "scripts/upload-dataset.ts",
    "content": "/**\n * Regenerates and uploads the dataset to HuggingFace\n *\n * Usage:\n *   HF_TOKEN=xxx npx tsx scripts/upload-dataset.ts [dataset-dir] [repo-name]\n *\n * Arguments:\n *   dataset-dir - Directory containing the dataset with data/ subfolder\n *                 (default: ./dataset)\n *   repo-name   - HuggingFace repository name (default: llamaindex/liteparse_cicd_data)\n *\n * Environment variables:\n *   HF_TOKEN - HuggingFace API token with write access\n *\n * This script:\n * 1. Regenerates metadata.jsonl by re-running liteparse on data/ in the dataset\n * 2. Uploads to HuggingFace using the huggingface_hub API\n */\n\nimport { execSync } from \"child_process\";\nimport * as path from \"path\";\n\nconst DEFAULT_OUTPUT_DIR = path.join(import.meta.dirname, \"..\", \"dataset\");\nconst DEFAULT_REPO = \"llamaindex/liteparse_cicd_data\";\n\nasync function main() {\n  const datasetDir = process.argv[2] || DEFAULT_OUTPUT_DIR;\n  const repoName = process.argv[3] || DEFAULT_REPO;\n  const hfToken = process.env.HF_TOKEN;\n\n  if (!hfToken) {\n    console.error(\"Error: HF_TOKEN environment variable is required\");\n    console.error(\"Get a token from https://huggingface.co/settings/tokens\");\n    process.exit(1);\n  }\n\n  const documentsDir = path.join(datasetDir, \"data\");\n\n  console.log(\"LiteParse Dataset Upload\");\n  console.log(\"========================\");\n  console.log(`Dataset: ${datasetDir}`);\n  console.log(`Documents: ${documentsDir}`);\n  console.log(`Repo: ${repoName}`);\n  console.log();\n\n  // Step 1: Regenerate dataset from documents in the dataset directory\n  console.log(\"Step 1: Regenerating dataset from existing documents...\");\n  try {\n    // Pass both output dir and source docs dir (data/ within the dataset)\n    execSync(`npx tsx scripts/create-dataset.ts \"${datasetDir}\" \"${documentsDir}\"`, {\n      cwd: path.join(import.meta.dirname, \"..\"),\n      stdio: \"inherit\",\n    });\n  } catch (error) {\n    console.error(\"Failed to generate dataset\");\n    process.exit(1);\n  }\n\n  // Step 2: Upload to HuggingFace\n  console.log(\"\\nStep 2: Uploading to HuggingFace...\");\n  try {\n    // Use hf cli to upload\n    // This requires hf cli to be installed: brew install huggingface-cli\n    execSync(\n      `hf upload ${repoName} \"${datasetDir}\" --repo-type dataset --token \"${hfToken}\"`,\n      {\n        cwd: path.join(import.meta.dirname, \"..\"),\n        stdio: \"inherit\",\n      }\n    );\n    console.log(\"\\n✓ Dataset uploaded successfully!\");\n    console.log(`  View at: https://huggingface.co/datasets/${repoName}`);\n  } catch (error) {\n    console.error(\"Failed to upload to HuggingFace\");\n    console.error(\"Make sure hf cli is installed: brew install huggingface-cli\");\n    process.exit(1);\n  }\n}\n\nmain().catch((error) => {\n  console.error(\"Fatal error:\", error);\n  process.exit(1);\n});\n"
  },
  {
    "path": "src/conversion/README.md",
    "content": "# src/conversion/\n\nMulti-format document conversion to PDF using external tools.\n\n## Files\n\n### convertToPdf.ts\n**Converts non-PDF documents to PDF for parsing.**\n\nLiteParse's core parsing works on PDFs. This module extends support to 50+ formats by converting them to PDF first using system tools.\n\n**Supported Formats:**\n\n| Category | Extensions |\n|----------|------------|\n| Office | .doc, .docx, .docm, .dot, .dotm, .dotx, .odt, .ott, .rtf, .pages |\n| Presentations | .ppt, .pptx, .pptm, .pot, .potm, .potx, .odp, .otp, .key |\n| Spreadsheets | .xls, .xlsx, .xlsm, .xlsb, .ods, .ots, .csv, .tsv, .numbers |\n| Images | .jpg, .jpeg, .png, .gif, .bmp, .tiff, .tif, .webp, .svg |\n| Web | .htm, .html, .xhtml (not yet implemented) |\n\n**External Dependencies:**\n- **LibreOffice** - For office documents and spreadsheets\n  - macOS: `brew install --cask libreoffice`\n  - Ubuntu: `apt-get install libreoffice`\n- **ImageMagick** - For images\n  - macOS: `brew install imagemagick`\n  - Ubuntu: `apt-get install imagemagick`\n  - Windows: LiteParse resolves the executable path and validates that the binary is actually ImageMagick, avoiding false matches against the built-in `C:\\Windows\\System32\\convert.exe`\n\n**Key Functions:**\n\n`convertToPdf(filePath)` - Main entry point for file path input\n- Returns `ConversionResult` with `pdfPath` and `originalExtension`\n- Returns `ConversionPassthrough` with `content` for text-based formats (e.g. .txt, .csv)\n- Returns `ConversionError` with `message` and `code` on failure\n- If already PDF, returns path unchanged\n\n`convertBufferToPdf(data)` - Entry point for buffer input\n- Detects format from magic bytes, writes to temp file, then delegates to `convertToPdf`\n- Used when `LiteParse.parse()` receives a non-PDF `Buffer` or `Uint8Array`\n\n`cleanupConversionFiles(pdfPath)` - Removes temp files after parsing\n- Only deletes files in the configured temp directory (`LITEPARSE_TMPDIR` or OS default)\n- Called by `LiteParse.parse()` after processing\n\n`getTmpDir()` - Returns the temp directory for LiteParse operations\n- Respects the `LITEPARSE_TMPDIR` environment variable\n- Falls back to `os.tmpdir()`\n\n`guessFileExtension(filePath)` - Detects format from extension or magic bytes\n- Checks file extension first\n- Falls back to magic byte detection (PDF, PNG, JPEG, ZIP-based)\n- Returns `null` when format cannot be determined\n\n`guessExtensionFromBuffer(data)` - Detects format from raw bytes using magic bytes\n- Supports PDF, PNG, JPEG, TIFF (both endians), and ZIP-based formats\n- Returns `null` when format cannot be determined (e.g. plain text)\n- Used by `convertBufferToPdf` to determine the temp file extension\n\n**Design Decisions:**\n\n1. **External tools over native parsers**: Using LibreOffice and ImageMagick provides broad format support with minimal code. Trade-off is external dependency requirement.\n\n2. **Subprocess-based**: Conversion runs as separate process to isolate crashes and memory issues.\n\n3. **Temporary file management**: Converted PDFs go to the configured temp directory (`LITEPARSE_TMPDIR` env var or OS default), cleaned up after parsing.\n\n4. **Timeout handling**: 2 minutes for LibreOffice, 1 minute for ImageMagick.\n\n5. **Executable validation on Windows**: Image conversion validates the resolved executable path and probes the binary with `-version` so Windows `convert.exe` is never mistaken for ImageMagick.\n\n6. **Magic byte fallback**: Handles files without extensions or with wrong extensions.\n\n**Error Codes:**\n- `FILE_NOT_FOUND` - Input file doesn't exist\n- `UNSUPPORTED_FORMAT` - Format not supported\n- `CONVERSION_ERROR` - Conversion process failed\n"
  },
  {
    "path": "src/conversion/convertToPdf.test.ts",
    "content": "import os from \"os\";\nimport path from \"path\";\nimport { vi, describe, it, expect, afterEach } from \"vitest\";\n\ninterface SpawnPlan {\n  stdout?: string;\n  stderr?: string;\n  code?: number;\n  error?: Error;\n}\n\nconst libreOfficePath = \"C:\\\\Program Files\\\\LibreOffice\\\\program\\\\soffice.exe\\n\";\nconst imageMagickPath = \"C:\\\\Program Files\\\\ImageMagick\\\\magick.exe\\n\";\nconst imageMagickVersion = \"Version: ImageMagick 7.1.2-18 Q16-HDRI\\n\";\n\nconst mockFileTypeFromFile = vi.fn();\nvi.mock(\"file-type\", () => ({\n  fileTypeFromFile: (...args: unknown[]) => mockFileTypeFromFile(...args),\n  fileTypeFromBuffer: vi.fn(async (data: Buffer | Uint8Array) => {\n    // Replicate enough detection to validate the wrapper\n    if (\n      data.length >= 4 &&\n      data[0] === 0x25 &&\n      data[1] === 0x50 &&\n      data[2] === 0x44 &&\n      data[3] === 0x46\n    ) {\n      return { ext: \"pdf\", mime: \"application/pdf\" };\n    }\n    if (\n      data.length >= 8 &&\n      data[0] === 0x89 &&\n      data[1] === 0x50 &&\n      data[2] === 0x4e &&\n      data[3] === 0x47\n    ) {\n      return { ext: \"png\", mime: \"image/png\" };\n    }\n    if (data.length >= 3 && data[0] === 0xff && data[1] === 0xd8 && data[2] === 0xff) {\n      return { ext: \"jpg\", mime: \"image/jpeg\" };\n    }\n    if (\n      data.length >= 4 &&\n      ((data[0] === 0x49 && data[1] === 0x49 && data[2] === 0x2a && data[3] === 0x00) ||\n        (data[0] === 0x4d && data[1] === 0x4d && data[2] === 0x00 && data[3] === 0x2a))\n    ) {\n      return { ext: \"tif\", mime: \"image/tiff\" };\n    }\n    if (data.length >= 4 && data[0] === 0x50 && data[1] === 0x4b) {\n      return { ext: \"zip\", mime: \"application/zip\" };\n    }\n    return undefined;\n  }),\n}));\n\nconst { spawnPlans, enqueueSpawnPlan, spawnMock } = vi.hoisted(() => {\n  class MockEmitter {\n    private listeners = new Map<string, Array<(...args: unknown[]) => void>>();\n\n    on(event: string, cb: (...args: unknown[]) => void) {\n      const existing = this.listeners.get(event) ?? [];\n      existing.push(cb);\n      this.listeners.set(event, existing);\n      return this;\n    }\n\n    emit(event: string, ...args: unknown[]) {\n      for (const cb of this.listeners.get(event) ?? []) {\n        cb(...args);\n      }\n    }\n  }\n\n  const plans: SpawnPlan[] = [];\n\n  function enqueuePlan(plan: SpawnPlan) {\n    plans.push(plan);\n  }\n\n  const mock = vi.fn(() => {\n    const plan = plans.shift() ?? { code: 0 };\n    const stdout = new MockEmitter();\n    const stderr = new MockEmitter();\n\n    const proc = {\n      stdout,\n      stderr,\n      kill: vi.fn(),\n      on: vi.fn((event: string, cb: (...args: unknown[]) => void) => {\n        if (event === \"error\" && plan.error) {\n          queueMicrotask(() => cb(plan.error));\n        }\n        if (event === \"close\" && !plan.error) {\n          queueMicrotask(() => {\n            if (plan.stdout) stdout.emit(\"data\", plan.stdout);\n            if (plan.stderr) stderr.emit(\"data\", plan.stderr);\n            cb(plan.code ?? 0);\n          });\n        }\n        return proc;\n      }),\n    };\n\n    return proc;\n  });\n\n  return {\n    spawnPlans: plans,\n    enqueueSpawnPlan: enqueuePlan,\n    spawnMock: mock,\n  };\n});\n\nfunction enqueueSpawnPlans(...plans: SpawnPlan[]): void {\n  for (const plan of plans) {\n    enqueueSpawnPlan(plan);\n  }\n}\n\nfunction enqueueMissingCommandLookups(count: number): void {\n  for (let index = 0; index < count; index += 1) {\n    enqueueSpawnPlan({ code: 1 });\n  }\n}\n\nfunction enqueueLibreOfficeLookup(): void {\n  enqueueSpawnPlans({ code: 1 }, { stdout: libreOfficePath, code: 0 });\n}\n\nfunction enqueueImageMagickLookup(): void {\n  enqueueSpawnPlans({ stdout: imageMagickPath, code: 0 }, { stdout: imageMagickVersion, code: 0 });\n}\n\nvi.mock(\"child_process\", () => ({\n  spawn: spawnMock,\n}));\n\nvi.mock(\"fs\", async () => {\n  const actual = await vi.importActual<typeof import(\"fs\")>(\"fs\");\n  return {\n    ...actual,\n    promises: {\n      access: vi.fn(async (path: string, _mode?: number) => {\n        const toErrorPath = [\n          \"/Applications/LibreOffice.app/Contents/MacOS/soffice\",\n          \"/Applications/LibreOffice.app/Contents/MacOS/libreoffice\",\n          \"C:\\\\Program Files\\\\Libreoffice\\\\program\\\\soffice.exe\",\n          \"./test_fail.pdf\",\n          \"test_fail.pdf\",\n          \"test.docx\",\n        ];\n        if (toErrorPath.includes(path)) {\n          throw new Error(\"unaccessible\");\n        }\n        return;\n      }),\n      mkdtemp: vi.fn(async () => {\n        return \"/tmp/test\";\n      }),\n      readFile: vi.fn(async () => {\n        return \"hello world\";\n      }),\n    },\n  };\n});\n\nimport {\n  guessFileExtension,\n  guessExtensionFromBuffer,\n  findImageMagickCommand,\n  findLibreOfficeCommand,\n  convertOfficeDocument,\n  convertImageToPdf,\n  convertToPdf,\n  getTmpDir,\n} from \"./convertToPdf\";\n\nafterEach(() => {\n  spawnPlans.length = 0;\n  spawnMock.mockClear();\n  mockFileTypeFromFile.mockReset();\n  vi.restoreAllMocks();\n});\n\ndescribe(\"test guessFileExtension\", () => {\n  it(\"detects PDF via file-type\", async () => {\n    mockFileTypeFromFile.mockResolvedValue({ ext: \"pdf\", mime: \"application/pdf\" });\n    expect(await guessFileExtension(\"/some/file\")).toBe(\".pdf\");\n  });\n\n  it(\"detects PNG via file-type\", async () => {\n    mockFileTypeFromFile.mockResolvedValue({ ext: \"png\", mime: \"image/png\" });\n    expect(await guessFileExtension(\"/some/file\")).toBe(\".png\");\n  });\n\n  it(\"returns null when file-type returns undefined\", async () => {\n    mockFileTypeFromFile.mockResolvedValue(undefined);\n    expect(await guessFileExtension(\"/some/file\")).toBeNull();\n  });\n\n  it(\"returns extension directly if present\", async () => {\n    expect(await guessFileExtension(\"/some/file.pdf\")).toBe(\".pdf\");\n  });\n});\n\ndescribe(\"test command availability\", () => {\n  it(\"libreoffice available\", async () => {\n    enqueueLibreOfficeLookup();\n\n    const result = await findLibreOfficeCommand();\n    expect(result).toBe(\"libreoffice\");\n  });\n\n  it(\"libreoffice not available\", async () => {\n    enqueueMissingCommandLookups(4);\n\n    const result = await findLibreOfficeCommand();\n    expect(result).toBeNull();\n  });\n\n  it(\"imagemagick available\", async () => {\n    enqueueImageMagickLookup();\n\n    const result = await findImageMagickCommand();\n    expect(result).toStrictEqual({\n      command: imageMagickPath.trim(),\n      args: [],\n      resolvedPath: imageMagickPath.trim(),\n    });\n  });\n\n  it(\"imagemagick not available\", async () => {\n    enqueueMissingCommandLookups(2);\n\n    const result = await findImageMagickCommand();\n    expect(result).toBeNull();\n  });\n\n  it(\"rejects Windows system convert.exe\", async () => {\n    enqueueSpawnPlans({ code: 1 }, { stdout: \"C:\\\\Windows\\\\System32\\\\convert.exe\\n\", code: 0 });\n\n    const result = await findImageMagickCommand();\n    expect(result).toBeNull();\n  });\n\n  it(\"accepts ImageMagick convert on non-Windows\", async () => {\n    vi.spyOn(process, \"platform\", \"get\").mockReturnValue(\"linux\");\n    enqueueSpawnPlans(\n      { code: 1 },\n      { stdout: \"/usr/bin/convert\\n\", code: 0 },\n      { stdout: \"Version: ImageMagick 6.9.12-98 Q16\\n\", code: 0 }\n    );\n\n    const result = await findImageMagickCommand();\n    expect(result).toStrictEqual({\n      command: \"/usr/bin/convert\",\n      args: [],\n      resolvedPath: \"/usr/bin/convert\",\n    });\n  });\n});\n\ndescribe(\"test convertOfficeDocument\", () => {\n  it(\"conversion succeeds\", async () => {\n    enqueueLibreOfficeLookup();\n    enqueueSpawnPlan({ stdout: \"conversion successful\", code: 0 });\n\n    const result = await convertOfficeDocument(\"test.docx\", \"./\");\n    expect(result).toBe(\"test.pdf\");\n  });\n\n  it(\"conversion fails (command not found)\", async () => {\n    enqueueMissingCommandLookups(4);\n\n    await expect(convertOfficeDocument(\"test_command.docx\", \"./\")).rejects.toThrow(\n      \"LibreOffice is not installed. Please install LibreOffice to convert office documents. On macOS: brew install --cask libreoffice, On Ubuntu: apt-get install libreoffice, On Windows: choco install libreoffice-fresh\"\n    );\n  });\n\n  it(\"conversion fails (output not found)\", async () => {\n    enqueueLibreOfficeLookup();\n    enqueueSpawnPlan({ stdout: \"conversion successful\", code: 0 });\n\n    await expect(convertOfficeDocument(\"test_fail.docx\", \"./\")).rejects.toThrow(\n      \"LibreOffice conversion succeeded but output PDF not found\"\n    );\n  });\n});\n\ndescribe(\"test convertImageToPdf\", () => {\n  it(\"conversion succeeds\", async () => {\n    enqueueImageMagickLookup();\n    enqueueSpawnPlan({ stdout: \"conversion successful\", code: 0 });\n\n    const result = await convertImageToPdf(\"test.png\", \"./\");\n    expect(result).toBe(\"test.pdf\");\n  });\n\n  it(\"conversion fails (command not found)\", async () => {\n    enqueueMissingCommandLookups(2);\n\n    await expect(convertImageToPdf(\"test_command.png\", \"./\")).rejects.toThrow(\n      \"ImageMagick is not installed. Please install ImageMagick to convert images. On macOS: brew install imagemagick, On Ubuntu: apt-get install imagemagick, On Windows: choco install imagemagick.app\"\n    );\n  });\n});\n\ndescribe(\"test convertToPdf\", () => {\n  it(\"convert PDF fails because file not found\", async () => {\n    const result = await convertToPdf(\"test.docx\");\n    expect(result).toStrictEqual({\n      message: `File not found: test.docx`,\n      code: \"FILE_NOT_FOUND\",\n    });\n  });\n\n  it(\"convert an office document (word)\", async () => {\n    enqueueLibreOfficeLookup();\n    enqueueSpawnPlan({ stdout: \"conversion successful\", code: 0 });\n\n    const result = await convertToPdf(\"test_1.docx\");\n    expect(result).toStrictEqual({\n      pdfPath: path.join(\"/tmp/test\", \"test_1.pdf\"),\n      originalExtension: \".docx\",\n    });\n  });\n\n  it(\"convert an office document (xlsx)\", async () => {\n    enqueueLibreOfficeLookup();\n    enqueueSpawnPlan({ stdout: \"conversion successful\", code: 0 });\n\n    const result = await convertToPdf(\"test.xlsx\");\n    expect(result).toStrictEqual({\n      pdfPath: path.join(\"/tmp/test\", \"test.pdf\"),\n      originalExtension: \".xlsx\",\n    });\n  });\n\n  it(\"convert an image\", async () => {\n    enqueueImageMagickLookup();\n    enqueueSpawnPlan({ stdout: \"conversion successful\", code: 0 });\n\n    const result = await convertToPdf(\"test.png\");\n    expect(result).toStrictEqual({\n      pdfPath: path.join(\"/tmp/test\", \"test.pdf\"),\n      originalExtension: \".png\",\n    });\n  });\n\n  it(\"convert a text file\", async () => {\n    const result = await convertToPdf(\"test.txt\");\n    expect(result).toStrictEqual({\n      content: \"hello world\",\n    });\n  });\n});\n\ndescribe(\"test guessExtensionFromBuffer\", () => {\n  it(\"detects PDF from magic bytes\", async () => {\n    const pdfBytes = Buffer.from(\"%PDF-1.4 some content\");\n    expect(await guessExtensionFromBuffer(pdfBytes)).toBe(\".pdf\");\n  });\n\n  it(\"detects PNG from magic bytes\", async () => {\n    const pngBytes = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);\n    expect(await guessExtensionFromBuffer(pngBytes)).toBe(\".png\");\n  });\n\n  it(\"detects JPEG from magic bytes\", async () => {\n    const jpegBytes = Buffer.from([0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10]);\n    expect(await guessExtensionFromBuffer(jpegBytes)).toBe(\".jpg\");\n  });\n\n  it(\"detects TIFF (little-endian) from magic bytes\", async () => {\n    const tiffBytes = Buffer.from([0x49, 0x49, 0x2a, 0x00]);\n    expect(await guessExtensionFromBuffer(tiffBytes)).toBe(\".tif\");\n  });\n\n  it(\"detects TIFF (big-endian) from magic bytes\", async () => {\n    const tiffBytes = Buffer.from([0x4d, 0x4d, 0x00, 0x2a]);\n    expect(await guessExtensionFromBuffer(tiffBytes)).toBe(\".tif\");\n  });\n\n  it(\"detects ZIP-based formats from magic bytes\", async () => {\n    const zipBytes = Buffer.from([0x50, 0x4b, 0x03, 0x04]);\n    expect(await guessExtensionFromBuffer(zipBytes)).toBe(\".zip\");\n  });\n\n  it(\"returns null for unknown bytes\", async () => {\n    const unknownBytes = Buffer.from([0x00, 0x01, 0x02, 0x03]);\n    expect(await guessExtensionFromBuffer(unknownBytes)).toBeNull();\n  });\n\n  it(\"works with Uint8Array input\", async () => {\n    const pdfBytes = new Uint8Array(Buffer.from(\"%PDF-1.7\"));\n    expect(await guessExtensionFromBuffer(pdfBytes)).toBe(\".pdf\");\n  });\n});\n\ndescribe(\"test getTmpDir\", () => {\n  const originalEnv = process.env.LITEPARSE_TMPDIR;\n\n  afterEach(() => {\n    if (originalEnv === undefined) {\n      delete process.env.LITEPARSE_TMPDIR;\n    } else {\n      process.env.LITEPARSE_TMPDIR = originalEnv;\n    }\n  });\n\n  it(\"returns LITEPARSE_TMPDIR when set\", () => {\n    process.env.LITEPARSE_TMPDIR = \"/custom/tmp\";\n    expect(getTmpDir()).toBe(\"/custom/tmp\");\n  });\n\n  it(\"falls back to os.tmpdir() when LITEPARSE_TMPDIR is not set\", () => {\n    delete process.env.LITEPARSE_TMPDIR;\n    expect(getTmpDir()).toBe(os.tmpdir());\n  });\n});\n"
  },
  {
    "path": "src/conversion/convertToPdf.ts",
    "content": "import { promises as fs, constants as fsConstants } from \"fs\";\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport os from \"os\";\nimport { fileTypeFromFile, fileTypeFromBuffer } from \"file-type\";\n\n/**\n * Returns the temp directory for LiteParse operations.\n * Respects the `LITEPARSE_TMPDIR` environment variable, falling back to the OS default.\n */\nexport function getTmpDir(): string {\n  return process.env.LITEPARSE_TMPDIR || os.tmpdir();\n}\n\nexport interface ConversionResult {\n  pdfPath: string;\n  originalExtension: string;\n}\n\nexport interface ConversionError {\n  message: string;\n  code: string;\n}\n\nexport interface ConversionPassthrough {\n  content: string;\n}\n\ninterface ResolvedCommand {\n  command: string;\n  args: string[];\n  resolvedPath: string;\n}\n\n// File extension categories\nexport const officeExtensions = [\n  \".doc\",\n  \".docx\",\n  \".docm\",\n  \".dot\",\n  \".dotm\",\n  \".dotx\",\n  \".odt\",\n  \".ott\",\n  \".ppt\",\n  \".pptx\",\n  \".pptm\",\n  \".pot\",\n  \".potm\",\n  \".potx\",\n  \".odp\",\n  \".otp\",\n  \".rtf\",\n  \".pages\",\n  \".key\",\n];\n\nexport const spreadsheetExtensions = [\n  \".xls\",\n  \".xlsx\",\n  \".xlsm\",\n  \".xlsb\",\n  \".ods\",\n  \".ots\",\n  \".csv\",\n  \".tsv\",\n  \".numbers\",\n];\n\nexport const imageExtensions = [\n  \".jpg\",\n  \".jpeg\",\n  \".png\",\n  \".gif\",\n  \".bmp\",\n  \".tiff\",\n  \".tif\",\n  \".webp\",\n  \".svg\",\n];\n\nexport const htmlExtensions = [\".htm\", \".html\", \".xhtml\"];\n\n/**\n * Guess file extension from file content using file-type magic byte detection.\n * Returns the path's own extension if present, otherwise inspects file bytes.\n */\nexport async function guessFileExtension(filePath: string): Promise<string | null> {\n  const ext = path.extname(filePath).toLowerCase();\n  if (ext) {\n    return ext;\n  }\n\n  const result = await fileTypeFromFile(filePath);\n  if (result) {\n    return `.${result.ext}`;\n  }\n\n  return null;\n}\n\n/**\n * Execute command with timeout\n */\nasync function executeCommand(command: string, args: string[], timeoutMs = 60000): Promise<string> {\n  return new Promise((resolve, reject) => {\n    const proc = spawn(command, args, {\n      stdio: [\"ignore\", \"pipe\", \"pipe\"],\n    });\n\n    let stdout = \"\";\n    let stderr = \"\";\n\n    proc.stdout?.on(\"data\", (data) => {\n      stdout += data.toString();\n    });\n\n    proc.stderr?.on(\"data\", (data) => {\n      stderr += data.toString();\n    });\n\n    const timeout = setTimeout(() => {\n      proc.kill();\n      reject(new Error(`Command timeout after ${timeoutMs}ms`));\n    }, timeoutMs);\n\n    proc.on(\"close\", (code) => {\n      clearTimeout(timeout);\n      if (code === 0) {\n        resolve(stdout);\n      } else {\n        reject(new Error(`Command failed with code ${code}: ${stderr}`));\n      }\n    });\n\n    proc.on(\"error\", (err) => {\n      clearTimeout(timeout);\n      reject(err);\n    });\n  });\n}\n\n/* Execute a command for PowerShell */\nasync function executePowerShell(command: string, timeoutMs = 60000) {\n  return executeCommand(\"powershell\", [\"-NoProfile\", \"-Command\", command], timeoutMs);\n}\n\nfunction getResolvedPathFromOutput(output: string, useLastLine = false): string | null {\n  const lines = output\n    .split(/\\r?\\n/)\n    .map((line) => line.trim())\n    .filter(Boolean);\n\n  if (lines.length === 0) {\n    return null;\n  }\n\n  return useLastLine ? lines.at(-1) || null : lines[0];\n}\n\n/**\n * Resolve the actual executable path for a command.\n */\nasync function resolveCommandPath(command: string): Promise<string | null> {\n  try {\n    if (process.platform === \"win32\") {\n      const output = await executePowerShell(\n        `(Get-Command '${command}' -ErrorAction Stop).Source`,\n        5000\n      );\n      return getResolvedPathFromOutput(output, true);\n    }\n\n    const output = await executeCommand(\"which\", [command], 5000);\n    return getResolvedPathFromOutput(output);\n  } catch {\n    return null;\n  }\n}\n\n/**\n * Check if a command is available\n */\nasync function isCommandAvailable(command: string): Promise<boolean> {\n  try {\n    await executeCommand(\"which\", [command], 5000);\n    return true;\n  } catch {\n    return false;\n  }\n}\n\nasync function isCommandAvailableWindows(command: string): Promise<boolean> {\n  try {\n    await executePowerShell(`Get-Command ${command}`, 5000);\n    return true;\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Check if a file path exists and is executable\n */\nasync function isPathExecutable(filePath: string): Promise<boolean> {\n  try {\n    await fs.access(filePath, fsConstants.X_OK);\n    return true;\n  } catch {\n    return false;\n  }\n}\n\nfunction isWindowsSystemConvert(filePath: string): boolean {\n  const normalizedPath = path.win32.normalize(filePath).toLowerCase();\n  const system32Convert = path.win32\n    .normalize(path.join(process.env.SystemRoot || \"C:\\\\Windows\", \"System32\", \"convert.exe\"))\n    .toLowerCase();\n  return normalizedPath === system32Convert;\n}\n\nasync function isImageMagickBinary(executablePath: string, args: string[] = []): Promise<boolean> {\n  try {\n    const output = await executeCommand(executablePath, [...args, \"-version\"], 5000);\n    return output.toLowerCase().includes(\"imagemagick\");\n  } catch {\n    return false;\n  }\n}\n\nasync function resolveImageMagickCommand(\n  command: \"magick\" | \"convert\"\n): Promise<ResolvedCommand | null> {\n  const resolvedPath = await resolveCommandPath(command);\n  if (!resolvedPath) {\n    return null;\n  }\n\n  if (\n    command === \"convert\" &&\n    process.platform === \"win32\" &&\n    isWindowsSystemConvert(resolvedPath)\n  ) {\n    return null;\n  }\n\n  if (!(await isImageMagickBinary(resolvedPath))) {\n    return null;\n  }\n\n  return { command: resolvedPath, args: [], resolvedPath };\n}\n\n/**\n * Find LibreOffice command - handles different installation methods\n */\nexport async function findLibreOfficeCommand(): Promise<string | null> {\n  // Check for 'libreoffice' in PATH (Linux, some macOS setups)\n  if (\n    (await isCommandAvailable(\"libreoffice\")) ||\n    (await isCommandAvailableWindows(\"libreoffice\"))\n  ) {\n    return \"libreoffice\";\n  }\n\n  // Check for 'soffice' in PATH\n  if ((await isCommandAvailable(\"soffice\")) || (await isCommandAvailableWindows(\"soffice\"))) {\n    return \"soffice\";\n  }\n\n  // macOS: Check standard application paths\n  const macOSPaths = [\n    \"/Applications/LibreOffice.app/Contents/MacOS/soffice\",\n    \"/Applications/LibreOffice.app/Contents/MacOS/libreoffice\",\n  ];\n\n  const windowsPaths = [\"C:\\\\Program Files\\\\Libreoffice\\\\program\\\\soffice.exe\"];\n\n  for (const libPath of macOSPaths) {\n    if (await isPathExecutable(libPath)) {\n      return libPath;\n    }\n  }\n\n  for (const libPath of windowsPaths) {\n    if (await isPathExecutable(libPath)) {\n      return libPath;\n    }\n  }\n\n  return null;\n}\n\n/**\n * Find ImageMagick command - handles v6 (convert) and v7 (magick)\n */\nexport async function findImageMagickCommand(): Promise<ResolvedCommand | null> {\n  return (\n    (await resolveImageMagickCommand(\"magick\")) ?? (await resolveImageMagickCommand(\"convert\"))\n  );\n}\n\n/**\n * Convert office documents using LibreOffice\n */\nexport async function convertOfficeDocument(\n  filePath: string,\n  outputDir: string,\n  password?: string\n): Promise<string> {\n  const libreOfficeCmd = await findLibreOfficeCommand();\n  if (!libreOfficeCmd) {\n    throw new Error(\n      \"LibreOffice is not installed. Please install LibreOffice to convert office documents. On macOS: brew install --cask libreoffice, On Ubuntu: apt-get install libreoffice, On Windows: choco install libreoffice-fresh\"\n    );\n  }\n\n  const args = [\"--headless\", \"--invisible\", \"--convert-to\", \"pdf\", \"--outdir\", outputDir];\n  if (password) {\n    args.push(`--infilter=:${password}`);\n  }\n  args.push(filePath);\n\n  await executeCommand(\n    libreOfficeCmd,\n    args,\n    120000 // 2 minutes timeout\n  );\n\n  // LibreOffice creates output with same name but .pdf extension\n  const baseName = path.basename(filePath, path.extname(filePath));\n  const pdfPath = path.join(outputDir, `${baseName}.pdf`);\n\n  // Verify the PDF was created\n  try {\n    await fs.access(pdfPath);\n    return pdfPath;\n  } catch {\n    throw new Error(\"LibreOffice conversion succeeded but output PDF not found\");\n  }\n}\n\n// Extensions that require Ghostscript for ImageMagick conversion\nconst ghostscriptRequiredExtensions = [\".svg\", \".eps\", \".ps\", \".ai\"];\n\n/**\n * Convert images to PDF using ImageMagick\n */\nexport async function convertImageToPdf(filePath: string, outputDir: string): Promise<string> {\n  const imageMagick = await findImageMagickCommand();\n  if (!imageMagick) {\n    throw new Error(\n      \"ImageMagick is not installed. Please install ImageMagick to convert images. On macOS: brew install imagemagick, On Ubuntu: apt-get install imagemagick, On Windows: choco install imagemagick.app\"\n    );\n  }\n\n  const ext = path.extname(filePath).toLowerCase();\n  const needsGhostscript = ghostscriptRequiredExtensions.includes(ext);\n\n  // Check for Ghostscript if needed for this file type\n  if (needsGhostscript) {\n    const hasGhostscript =\n      (await isCommandAvailable(\"gs\")) || (await isCommandAvailableWindows(\"gs\"));\n    if (!hasGhostscript) {\n      throw new Error(\n        `Ghostscript is required to convert ${ext.toUpperCase().slice(1)} files but is not installed. ` +\n          \"On macOS: brew install ghostscript, On Ubuntu: apt-get install ghostscript, On Windows: choco install ghostscript\"\n      );\n    }\n  }\n\n  const baseName = path.basename(filePath, path.extname(filePath));\n  const pdfPath = path.join(outputDir, `${baseName}.pdf`);\n\n  try {\n    await executeCommand(\n      imageMagick.command,\n      [...imageMagick.args, filePath, \"-density\", \"150\", \"-units\", \"PixelsPerInch\", pdfPath],\n      60000\n    );\n  } catch (error) {\n    const errorMsg = error instanceof Error ? error.message : String(error);\n    // Provide better error messages for common issues\n    if (errorMsg.includes(\"gs\") && errorMsg.includes(\"command not found\")) {\n      throw new Error(\n        `Ghostscript is required to convert ${ext.toUpperCase().slice(1)} files but is not installed. ` +\n          \"On macOS: brew install ghostscript, On Ubuntu: apt-get install ghostscript, On Windows: choco install ghostscript\",\n        {\n          cause: error,\n        }\n      );\n    }\n    if (errorMsg.includes(\"FailedToExecuteCommand\") && errorMsg.includes(\"gs\")) {\n      throw new Error(\n        `Ghostscript failed during ${ext.toUpperCase().slice(1)} conversion. ` +\n          \"Ensure Ghostscript is properly installed: brew install ghostscript\",\n        {\n          cause: error,\n        }\n      );\n    }\n    throw error;\n  }\n\n  return pdfPath;\n}\n\n/**\n * Main conversion function\n */\nexport async function convertToPdf(\n  filePath: string,\n  password?: string\n): Promise<ConversionResult | ConversionPassthrough | ConversionError> {\n  try {\n    // Check if file exists\n    try {\n      await fs.access(filePath);\n    } catch {\n      return {\n        message: `File not found: ${filePath}`,\n        code: \"FILE_NOT_FOUND\",\n      };\n    }\n\n    // Get file extension\n    const extension = await guessFileExtension(filePath);\n\n    // If already PDF, return as-is\n    if (extension === \".pdf\") {\n      return {\n        pdfPath: filePath,\n        originalExtension: extension,\n      };\n    }\n\n    // Unknown format or text-based — pass through as text\n    if (!extension) {\n      const content = await fs.readFile(filePath, \"utf-8\");\n      return { content };\n    }\n\n    // Create temp directory for output\n    const tmpDir = await fs.mkdtemp(path.join(getTmpDir(), \"liteparse-\"));\n\n    // Convert based on file type\n    let pdfPath: string;\n\n    if (officeExtensions.includes(extension)) {\n      pdfPath = await convertOfficeDocument(filePath, tmpDir, password);\n    } else if (spreadsheetExtensions.includes(extension)) {\n      pdfPath = await convertOfficeDocument(filePath, tmpDir, password);\n    } else if (imageExtensions.includes(extension)) {\n      pdfPath = await convertImageToPdf(filePath, tmpDir);\n    } else {\n      const content = await fs.readFile(filePath, \"utf-8\");\n      return { content };\n    }\n\n    return {\n      pdfPath,\n      originalExtension: extension,\n    };\n  } catch (error) {\n    return {\n      message: error instanceof Error ? error.message : String(error),\n      code: \"CONVERSION_ERROR\",\n    };\n  }\n}\n\n/**\n * Clean up temporary conversion files\n */\nexport async function cleanupConversionFiles(pdfPath: string): Promise<void> {\n  try {\n    // Only delete if in temp directory\n    if (pdfPath.includes(getTmpDir())) {\n      const dir = path.dirname(pdfPath);\n      await fs.rm(dir, { recursive: true, force: true });\n    }\n  } catch {\n    // Ignore cleanup errors\n  }\n}\n\n/**\n * Guess file extension from raw bytes using file-type magic byte detection.\n */\nexport async function guessExtensionFromBuffer(data: Buffer | Uint8Array): Promise<string | null> {\n  const result = await fileTypeFromBuffer(data);\n  if (result) {\n    return `.${result.ext}`;\n  }\n  return null;\n}\n\n/**\n * Convert a raw byte buffer to PDF by writing to a temp file and converting.\n * For PDF buffers, callers should skip this and pass data directly to the PDF engine.\n */\nexport async function convertBufferToPdf(\n  data: Buffer | Uint8Array,\n  password?: string\n): Promise<ConversionResult | ConversionPassthrough | ConversionError> {\n  const ext = await guessExtensionFromBuffer(data);\n\n  // Write buffer to temp file with detected extension (use .bin for unknown)\n  const tmpDir = await fs.mkdtemp(path.join(getTmpDir(), \"liteparse-\"));\n  const tmpPath = path.join(tmpDir, `input${ext || \".bin\"}`);\n  await fs.writeFile(tmpPath, data);\n\n  return convertToPdf(tmpPath, password);\n}\n"
  },
  {
    "path": "src/core/README.md",
    "content": "# src/core/\n\nThe core module contains the main orchestrator class, configuration management, and TypeScript type definitions that form the foundation of LiteParse.\n\n## Files\n\n### parser.ts\n**The main LiteParse class** - orchestrates the entire parsing pipeline.\n\n**Key Responsibilities:**\n- Initializes PDF and OCR engines based on configuration\n- Coordinates the document processing pipeline\n- Manages document lifecycle (load, process, cleanup)\n- Handles format conversion for non-PDF inputs\n\n**Public Methods:**\n- `parse(input, quiet?)` - Main entry point for document parsing. Accepts a file path (`string`), `Buffer`, or `Uint8Array`.\n- `screenshot(input, pageNumbers?, quiet?)` - Generate page screenshots. Accepts the same input types as `parse()`.\n- `getConfig()` - Returns current configuration\n\n**Pipeline Flow (in `parse()`):**\n1. **Input routing**: File paths go through `convertToPdf`; PDF buffers go directly to the engine (zero disk I/O); non-PDF buffers are written to temp for conversion via `convertBufferToPdf`\n2. Load PDF document with PDF engine\n3. Extract pages\n4. Run OCR on text-sparse pages/embedded images (passes image buffers directly to OCR engines — no temp files)\n5. Project pages to grid (spatial text reconstruction)\n6. Build bounding boxes (if enabled)\n7. Format output (JSON or text)\n8. Cleanup resources\n\n**Design Decisions:**\n- **Engine auto-detection**: If `ocrServerUrl` is provided, uses HTTP OCR; otherwise defaults to Tesseract.js for zero-setup experience\n- **Selective OCR**: Only runs OCR on pages with <100 characters of text OR pages with embedded images\n- **Progress logging to stderr**: Keeps stdout clean for piped output\n- **Graceful cleanup**: Always cleans up temp files and terminates OCR workers\n\n---\n\n### types.ts\n**TypeScript type definitions** for the entire library.\n\n**Configuration Types:**\n- `LiteParseConfig` - All configuration options\n- `LiteParseInput` - Accepted input types: `string | Buffer | Uint8Array`\n- `OutputFormat` - 'json' | 'text'\n\n**Data Types:**\n- `TextItem` - Individual text element with position, font, rotation\n- `ProjectionTextBox` - Extended text item with projection metadata (snap, anchors, etc.)\n- `BoundingBox` - Coordinates (x1, y1, x2, y2)\n- `ParsedPage` - Complete page data (text, textItems)\n- `ParseResult` - Final parse output\n- `ScreenshotResult` - Screenshot output with image buffer\n\n**Key Type Details:**\n\n`TextItem` contains:\n- Position: `x`, `y`, `width`, `height` (also `w`, `h` aliases)\n- Font info: `fontName`, `fontSize`\n- Rotation: `r` (degrees), `rx`/`ry` (rotated coordinates)\n- Markup: `markup` (highlight, underline, strikeout)\n- Layout hints: `vgap`, `isPlaceholder`\n\n`ProjectionTextBox` adds projection metadata:\n- `snap` - Alignment type ('left', 'right', 'center', or undefined for floating)\n- `leftAnchor`, `rightAnchor`, `centerAnchor` - Column anchor strings\n- `isDup` - Marks duplicate text items\n- `forceUnsnapped` - Override snap detection\n- `fromOCR` - Text came from OCR\n\n---\n\n### config.ts\n**Default configuration and merging logic.**\n\n**DEFAULT_CONFIG Values:**\n```typescript\n{\n  ocrLanguage: 'en',\n  ocrEnabled: true,\n  ocrServerUrl: undefined,  // Uses Tesseract if not set\n  maxPages: 1000,\n  dpi: 150,\n  outputFormat: 'json',\n  preciseBoundingBox: true,\n  preserveVerySmallText: false,\n  preserveLayoutAlignmentAcrossPages: false,\n}\n```\n\n**mergeConfig(userConfig)**\nSimple spread-based merge: `{ ...DEFAULT_CONFIG, ...userConfig }`\n\n**Design Decision:**\nThe merge is intentionally shallow. Users provide only the options they want to change. This keeps the API simple while ensuring all required fields exist.\n\n---\n\n## Common Modifications\n\n### Adding a new configuration option\n1. Add field to `LiteParseConfig` interface in `types.ts`\n2. Add default value in `DEFAULT_CONFIG` in `config.ts`\n3. Use the option in `parser.ts` or pass to relevant module\n\n### Adding a new output format\n1. Add to `OutputFormat` type in `types.ts`\n2. Create formatter in `src/output/`\n3. Add case to switch in `parser.ts` `parse()` method\n\n### Adding lifecycle hooks\nThe `parse()` method in `parser.ts` has clear pipeline stages. Add hooks between stages as needed (e.g., before/after OCR, before/after grid projection).\n"
  },
  {
    "path": "src/core/config.test.ts",
    "content": "import { describe, it, expect } from \"vitest\";\nimport { LiteParseConfig } from \"./types\";\nimport { DEFAULT_CONFIG, mergeConfig } from \"./config\";\n\ndescribe(\"test config\", () => {\n  it(\"test merge config with no partial config\", () => {\n    const user_config: Partial<LiteParseConfig> = {};\n    const config = mergeConfig(user_config);\n    expect(config).toStrictEqual(DEFAULT_CONFIG);\n  });\n  it(\"test merge config overrides defaults\", () => {\n    const user_config: Partial<LiteParseConfig> = {\n      ocrLanguage: \"fr\",\n      ocrServerUrl: \"http://localhost:8000\",\n      dpi: 200,\n    };\n    const config = mergeConfig(user_config);\n    expect(config.ocrLanguage).toBe(user_config.ocrLanguage);\n    expect(config.ocrServerUrl).toBe(user_config.ocrServerUrl);\n    expect(config.dpi).toBe(user_config.dpi);\n  });\n});\n"
  },
  {
    "path": "src/core/config.ts",
    "content": "import { LiteParseConfig } from \"./types.js\";\n\nexport const DEFAULT_CONFIG: LiteParseConfig = {\n  // OCR - defaults to in-process Tesseract for zero-setup experience\n  // If ocrServerUrl is provided, uses HTTP OCR instead\n  ocrLanguage: \"en\",\n  ocrEnabled: true,\n  ocrServerUrl: undefined, // If set, uses HTTP OCR; otherwise uses Tesseract\n  numWorkers: 4, // Number of pages to OCR in parallel\n\n  // Processing\n  maxPages: 1000,\n  targetPages: undefined,\n  dpi: 150,\n\n  // Output\n  outputFormat: \"json\",\n\n  // Features\n  preciseBoundingBox: true,\n  preserveVerySmallText: false,\n  preserveLayoutAlignmentAcrossPages: false,\n  password: undefined,\n};\n\nexport function mergeConfig(userConfig: Partial<LiteParseConfig>): LiteParseConfig {\n  return {\n    ...DEFAULT_CONFIG,\n    ...userConfig,\n  };\n}\n"
  },
  {
    "path": "src/core/parser.test.ts",
    "content": "import { vi, describe, it, expect } from \"vitest\";\n\nconst {\n  mockPages,\n  mockPdfDocument,\n  mockParsedPages,\n  mockBoundingBoxes,\n  mockPdfConvertedResult,\n  mockOcrResults,\n  mockParseResultJson,\n  mockParsedPagesOcr,\n  mockParseResultJsonOcr,\n  mockTextItems,\n  mockParsedPagesWithBoundingBoxes,\n  mockParsedPagesWithBoundingBoxesOcr,\n  mockScreenshotResults,\n} = vi.hoisted(() => {\n  const mockPdfConvertedResult = {\n    pdfPath: \"/tmp/converted.pdf\",\n    originalExtension: \".docx\",\n  };\n\n  const mockPdfDocument = {\n    numPages: 5,\n    data: new TextEncoder().encode(\"hello world\"),\n  };\n\n  const mockPages = [\n    {\n      pageNum: 1,\n      width: 612,\n      height: 792,\n      textItems: [],\n      paths: [],\n      images: [],\n      annotations: [],\n    },\n    {\n      pageNum: 2,\n      width: 612,\n      height: 792,\n      textItems: [],\n      paths: [],\n      images: [],\n    },\n    {\n      pageNum: 3,\n      width: 612,\n      height: 792,\n      textItems: [],\n      paths: [],\n      images: [],\n      annotations: [],\n    },\n    {\n      pageNum: 4,\n      width: 612,\n      height: 792,\n      textItems: [],\n      paths: [],\n      images: [],\n    },\n    {\n      pageNum: 5,\n      width: 612,\n      height: 792,\n      textItems: [],\n      paths: [],\n      images: [],\n      annotations: [],\n    },\n  ];\n\n  const mockBoundingBoxes = [{ x1: 0, y1: 0, x2: 300, y2: 400 }];\n\n  const mockParsedPages = [\n    {\n      pageNum: 1,\n      width: 612,\n      height: 792,\n      text: \"Sample text for page 1\",\n      textItems: [],\n      boundingBoxes: undefined,\n    },\n    {\n      pageNum: 2,\n      width: 612,\n      height: 792,\n      text: \"Sample text for page 2\",\n      textItems: [],\n    },\n    {\n      pageNum: 3,\n      width: 612,\n      height: 792,\n      text: \"Sample text for page 3\",\n      textItems: [],\n      boundingBoxes: undefined,\n    },\n    {\n      pageNum: 4,\n      width: 612,\n      height: 792,\n      text: \"Sample text for page 4\",\n      textItems: [],\n    },\n    {\n      pageNum: 5,\n      width: 612,\n      height: 792,\n      text: \"Sample text for page 5\",\n      textItems: [],\n      boundingBoxes: undefined,\n    },\n  ];\n\n  const mockParsedPagesWithBoundingBoxes = mockParsedPages.map((page) => ({\n    ...page,\n    boundingBoxes: mockBoundingBoxes,\n  }));\n\n  const mockOcrResults = [\n    { text: \"Hello World\", bbox: [10, 20, 200, 40], confidence: 0.98 },\n    { text: \"Sample text\", bbox: [10, 50, 180, 70], confidence: 0.85 },\n    { text: \"Page footer\", bbox: [10, 750, 300, 770], confidence: 0.76 },\n  ];\n\n  const mockTextItems = mockOcrResults\n    .filter((r) => r.confidence > 0.1) // Filter low confidence\n    .filter((r) => {\n      // Filter out OCR text that already exists in native PDF text\n      const ocrText = r.text.trim().toLowerCase();\n      return ocrText.length > 0;\n    })\n    .map((r) => ({\n      str: r.text,\n      x: r.bbox[0],\n      y: r.bbox[1],\n      width: r.bbox[2] - r.bbox[0],\n      height: r.bbox[3] - r.bbox[1],\n      w: r.bbox[2] - r.bbox[0],\n      h: r.bbox[3] - r.bbox[1],\n      fontName: \"OCR\",\n      fontSize: r.bbox[3] - r.bbox[1],\n      confidence: Math.round(r.confidence * 1000) / 1000,\n    }));\n\n  const mockTextItemsJson = mockOcrResults.map((r) => ({\n    text: r.text,\n    x: r.bbox[0],\n    y: r.bbox[1],\n    width: r.bbox[2] - r.bbox[0],\n    height: r.bbox[3] - r.bbox[1],\n    fontName: \"OCR\",\n    fontSize: r.bbox[3] - r.bbox[1],\n    confidence: Math.round(r.confidence * 1000) / 1000,\n  }));\n\n  const mockParsedPagesOcr = [\n    {\n      pageNum: 1,\n      width: 612,\n      height: 792,\n      text: \"Sample text for page 1\",\n      textItems: mockTextItems,\n      boundingBoxes: undefined,\n    },\n    {\n      pageNum: 2,\n      width: 612,\n      height: 792,\n      text: \"Sample text for page 2\",\n      textItems: mockTextItems,\n    },\n    {\n      pageNum: 3,\n      width: 612,\n      height: 792,\n      text: \"Sample text for page 3\",\n      textItems: mockTextItems,\n      boundingBoxes: undefined,\n    },\n    {\n      pageNum: 4,\n      width: 612,\n      height: 792,\n      text: \"Sample text for page 4\",\n      textItems: mockTextItems,\n    },\n    {\n      pageNum: 5,\n      width: 612,\n      height: 792,\n      text: \"Sample text for page 5\",\n      textItems: mockTextItems,\n      boundingBoxes: undefined,\n    },\n  ];\n\n  const mockParsedPagesWithBoundingBoxesOcr = mockParsedPagesOcr.map((page) => ({\n    ...page,\n    boundingBoxes: mockBoundingBoxes,\n  }));\n\n  const mockParseResultJson = {\n    pages: [\n      {\n        page: 1,\n        width: 612,\n        height: 792,\n        text: \"Sample text for page 1\",\n        textItems: [],\n        boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n      },\n      {\n        page: 2,\n        width: 612,\n        height: 792,\n        text: \"Sample text for page 2\",\n        textItems: [],\n        boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n      },\n      {\n        page: 3,\n        width: 612,\n        height: 792,\n        text: \"Sample text for page 3\",\n        textItems: [],\n        boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n      },\n      {\n        page: 4,\n        width: 612,\n        height: 792,\n        text: \"Sample text for page 4\",\n        textItems: [],\n        boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n      },\n      {\n        page: 5,\n        width: 612,\n        height: 792,\n        text: \"Sample text for page 5\",\n        textItems: [],\n        boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n      },\n    ],\n  };\n\n  const mockParseResultJsonOcr = {\n    pages: [\n      {\n        page: 1,\n        width: 612,\n        height: 792,\n        text: \"Sample text for page 1\",\n        textItems: mockTextItemsJson,\n        boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n      },\n      {\n        page: 2,\n        width: 612,\n        height: 792,\n        text: \"Sample text for page 2\",\n        textItems: mockTextItemsJson,\n        boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n      },\n      {\n        page: 3,\n        width: 612,\n        height: 792,\n        text: \"Sample text for page 3\",\n        textItems: mockTextItemsJson,\n        boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n      },\n      {\n        page: 4,\n        width: 612,\n        height: 792,\n        text: \"Sample text for page 4\",\n        textItems: mockTextItemsJson,\n        boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n      },\n      {\n        page: 5,\n        width: 612,\n        height: 792,\n        text: \"Sample text for page 5\",\n        textItems: mockTextItemsJson,\n        boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n      },\n    ],\n  };\n\n  const mockImageBuffer = Buffer.from(new Uint8Array([1, 2, 3, 4, 5]));\n  const mockScreenshotResults: ScreenshotResult[] = [\n    {\n      pageNum: 1,\n      width: 612,\n      height: 792,\n      imageBuffer: mockImageBuffer,\n    },\n    {\n      pageNum: 2,\n      width: 612,\n      height: 792,\n      imageBuffer: mockImageBuffer,\n    },\n    {\n      pageNum: 3,\n      width: 612,\n      height: 792,\n      imageBuffer: mockImageBuffer,\n    },\n    {\n      pageNum: 4,\n      width: 612,\n      height: 792,\n      imageBuffer: mockImageBuffer,\n    },\n    {\n      pageNum: 5,\n      width: 612,\n      height: 792,\n      imageBuffer: mockImageBuffer,\n    },\n  ];\n\n  return {\n    mockPdfConvertedResult,\n    mockPdfDocument,\n    mockPages,\n    mockParsedPages,\n    mockBoundingBoxes,\n    mockOcrResults,\n    mockParseResultJson,\n    mockParsedPagesOcr,\n    mockParseResultJsonOcr,\n    mockTextItems,\n    mockParsedPagesWithBoundingBoxes,\n    mockParsedPagesWithBoundingBoxesOcr,\n    mockScreenshotResults,\n  };\n});\n\nimport { LiteParse } from \"./parser\";\nimport { LiteParseConfig, ScreenshotResult } from \"./types\";\n\nvi.mock(\"../conversion/convertToPdf.js\", async () => {\n  const actual = await vi.importActual<typeof import(\"../conversion/convertToPdf.js\")>(\n    \"../conversion/convertToPdf.js\"\n  );\n  return {\n    ...actual,\n    convertToPdf: vi.fn(async () => {\n      return mockPdfConvertedResult;\n    }),\n    cleanupConversionFiles: vi.fn(async () => {}),\n  };\n});\n\nvi.mock(\"../engines/pdf/pdfjs.js\", async () => {\n  const actual =\n    await vi.importActual<typeof import(\"../engines/pdf/pdfjs.js\")>(\"../engines/pdf/pdfjs.js\");\n  return {\n    ...actual,\n    PdfJsEngine: vi.fn(\n      class {\n        constructor() {}\n\n        loadDocument = vi.fn().mockResolvedValue(mockPdfDocument);\n        extractAllPages = vi.fn().mockResolvedValue(mockPages);\n        extractPage = vi.fn().mockResolvedValue(mockPages[0]);\n        renderPageImage = vi.fn(async () => Buffer.from(new Uint8Array([1, 2, 3, 4, 5])));\n        close = vi.fn(async () => {});\n      }\n    ),\n  };\n});\n\nvi.mock(\"../engines/ocr/tesseract.js\", async () => {\n  const actual = await vi.importActual<typeof import(\"../engines/ocr/tesseract.js\")>(\n    \"../engines/ocr/tesseract.js\"\n  );\n  return {\n    ...actual,\n    TesseractEngine: vi.fn(\n      class {\n        constructor() {}\n\n        recognize = vi.fn().mockResolvedValue(mockOcrResults);\n      }\n    ),\n  };\n});\n\nvi.mock(\"../engines/ocr/http-simple.js\", async () => {\n  const actual = await vi.importActual<typeof import(\"../engines/ocr/http-simple.js\")>(\n    \"../engines/ocr/http-simple.js\"\n  );\n  return {\n    ...actual,\n    HttpOcrEngine: vi.fn(\n      class {\n        private url;\n\n        constructor(url: string) {\n          this.url = url;\n          if (this.url != (\"http://localhost:8000\" as string)) {\n            // works as an assertion that the URL is being passed to the class\n            // at init time\n            throw new Error(\"cannot accept a URL that is not http://localhost:8000\");\n          }\n        }\n\n        recognize = vi.fn().mockResolvedValue(mockOcrResults);\n      }\n    ),\n  };\n});\n\nvi.mock(\"../processing/grid.js\", async () => {\n  const actual =\n    await vi.importActual<typeof import(\"../processing/grid.js\")>(\"../processing/grid.js\");\n  return {\n    ...actual,\n    projectPagesToGrid: vi\n      .fn()\n      // these get modified, so we need to pass a deep copy of the array instead of the original one\n      .mockImplementationOnce(() => structuredClone(mockParsedPages)) // no ocr - text\n      .mockImplementationOnce(() => structuredClone(mockParsedPages)) // no ocr - json\n      .mockImplementationOnce(() => structuredClone(mockParsedPagesOcr)) // ocr (tesseract) - text\n      .mockImplementationOnce(() => structuredClone(mockParsedPagesOcr)) // ocr (tesseract) - json\n      .mockImplementationOnce(() => structuredClone(mockParsedPagesOcr)) // ocr (http) - text\n      .mockImplementationOnce(() => structuredClone(mockParsedPagesOcr)) // ocr (http) - json\n      .mockImplementationOnce(() => structuredClone(mockParsedPages)), //no bounding boxes\n  };\n});\n\nvi.mock(\"../processing/bbox.js\", async () => {\n  const actual =\n    await vi.importActual<typeof import(\"../processing/bbox.js\")>(\"../processing/bbox.js\");\n  return {\n    ...actual,\n    buildBoundingBoxes: vi.fn().mockReturnValue(mockBoundingBoxes),\n  };\n});\n\nvi.mock(\"../engines/pdf/pdfium-renderer.js\", async () => {\n  const actual = await vi.importActual<typeof import(\"../engines/pdf/pdfium-renderer.js\")>(\n    \"../engines/pdf/pdfium-renderer.js\"\n  );\n  return {\n    ...actual,\n    PdfiumRenderer: vi.fn(\n      class {\n        constructor() {}\n\n        loadDocument = vi.fn(async () => {});\n        closeDocument = vi.fn();\n        renderPageToBuffer = vi.fn(async () => Buffer.from(new Uint8Array([1, 2, 3, 4, 5])));\n        close = vi.fn(async () => {});\n      }\n    ),\n  };\n});\n\ndescribe(\"Parse tests\", () => {\n  it(\"test parse without OCR and text format\", async () => {\n    const config: Partial<LiteParseConfig> = { ocrEnabled: false, outputFormat: \"text\" };\n    const liteparse = new LiteParse(config);\n    expect(liteparse.getConfig().ocrEnabled).toBeFalsy();\n    expect(liteparse.getConfig().outputFormat).toBe(\"text\");\n    const result = await liteparse.parse(\"/tmp/test.docx\");\n    expect(result.json).toBeUndefined();\n    expect(result.text).toBe(mockParsedPages.map((p) => p.text).join(\"\\n\\n\"));\n    expect(result.pages).toStrictEqual(mockParsedPagesWithBoundingBoxes);\n  });\n\n  it(\"test parse without OCR and json format\", async () => {\n    const config: Partial<LiteParseConfig> = { ocrEnabled: false, outputFormat: \"json\" };\n    const liteparse = new LiteParse(config);\n    expect(liteparse.getConfig().ocrEnabled).toBeFalsy();\n    expect(liteparse.getConfig().outputFormat).toBe(\"json\");\n    const result = await liteparse.parse(\"/tmp/test.docx\");\n    expect(result.json).toBeDefined();\n    expect(result.json).toStrictEqual(mockParseResultJson);\n    expect(result.text).toBe(mockParsedPages.map((p) => p.text).join(\"\\n\\n\"));\n    expect(result.pages).toStrictEqual(mockParsedPagesWithBoundingBoxes);\n  });\n\n  it(\"test parse with OCR (tesseract) and text format\", async () => {\n    const config: Partial<LiteParseConfig> = {\n      ocrEnabled: true,\n      outputFormat: \"text\",\n      ocrServerUrl: undefined,\n    };\n    const liteparse = new LiteParse(config);\n    expect(liteparse.getConfig().ocrEnabled).toBeTruthy();\n    expect(liteparse.getConfig().outputFormat).toBe(\"text\");\n    expect(liteparse.getConfig().ocrServerUrl).toBeUndefined();\n    const result = await liteparse.parse(\"/tmp/test.docx\");\n    console.log(result.pages.at(0)?.textItems);\n    expect(\n      result.pages.filter((page) => {\n        return page.textItems.length > 0;\n      }).length\n    ).toBeGreaterThan(0);\n    expect(result.json).toBeUndefined();\n    expect(result.text).toBe(mockParsedPages.map((p) => p.text).join(\"\\n\\n\"));\n    expect(result.pages).toStrictEqual(mockParsedPagesWithBoundingBoxesOcr);\n  });\n\n  it(\"test parse with OCR (tesseract) and json format\", async () => {\n    const config: Partial<LiteParseConfig> = {\n      ocrEnabled: true,\n      outputFormat: \"json\",\n      ocrServerUrl: undefined,\n    };\n    const liteparse = new LiteParse(config);\n    expect(liteparse.getConfig().ocrEnabled).toBeTruthy();\n    expect(liteparse.getConfig().outputFormat).toBe(\"json\");\n    expect(liteparse.getConfig().ocrServerUrl).toBeUndefined();\n    const result = await liteparse.parse(\"/tmp/test.docx\");\n    expect(\n      result.pages.filter((page) => {\n        return page.textItems.length > 0;\n      }).length\n    ).toBe(result.pages.length);\n    expect(result.pages.at(0)!.textItems).toStrictEqual(mockTextItems);\n    expect(result.json).toBeDefined();\n    expect(result.json).toStrictEqual(mockParseResultJsonOcr);\n    expect(result.text).toBe(mockParsedPages.map((p) => p.text).join(\"\\n\\n\"));\n    expect(result.pages).toStrictEqual(mockParsedPagesWithBoundingBoxesOcr);\n  });\n\n  it(\"test parse with OCR (http) and text format\", async () => {\n    const config: Partial<LiteParseConfig> = {\n      ocrEnabled: true,\n      outputFormat: \"text\",\n      ocrServerUrl: \"http://localhost:8000\",\n    };\n    const liteparse = new LiteParse(config);\n    expect(liteparse.getConfig().ocrEnabled).toBeTruthy();\n    expect(liteparse.getConfig().outputFormat).toBe(\"text\");\n    expect(liteparse.getConfig().ocrServerUrl).toBe(\"http://localhost:8000\");\n    const result = await liteparse.parse(\"/tmp/test.docx\");\n    console.log(result.pages.at(0)?.textItems);\n    expect(\n      result.pages.filter((page) => {\n        return page.textItems.length > 0;\n      }).length\n    ).toBe(result.pages.length);\n    expect(result.pages.at(0)!.textItems).toStrictEqual(mockTextItems);\n    expect(result.json).toBeUndefined();\n    expect(result.text).toBe(mockParsedPages.map((p) => p.text).join(\"\\n\\n\"));\n    expect(result.pages).toStrictEqual(mockParsedPagesWithBoundingBoxesOcr);\n  });\n\n  it(\"test parse with OCR (http) and json format\", async () => {\n    const config: Partial<LiteParseConfig> = {\n      ocrEnabled: true,\n      outputFormat: \"json\",\n      ocrServerUrl: \"http://localhost:8000\",\n    };\n    const liteparse = new LiteParse(config);\n    expect(liteparse.getConfig().ocrEnabled).toBeTruthy();\n    expect(liteparse.getConfig().outputFormat).toBe(\"json\");\n    expect(liteparse.getConfig().ocrServerUrl).toBe(\"http://localhost:8000\");\n    const result = await liteparse.parse(\"/tmp/test.docx\");\n    expect(\n      result.pages.filter((page) => {\n        return page.textItems.length > 0;\n      }).length\n    ).toBe(result.pages.length);\n    expect(result.pages.at(0)!.textItems).toStrictEqual(mockTextItems);\n    expect(result.json).toBeDefined();\n    expect(result.json).toStrictEqual(mockParseResultJsonOcr);\n    expect(result.text).toBe(mockParsedPages.map((p) => p.text).join(\"\\n\\n\"));\n    expect(result.pages).toStrictEqual(mockParsedPagesWithBoundingBoxesOcr);\n  });\n\n  it(\"test without bounding boxes\", async () => {\n    const config: Partial<LiteParseConfig> = {\n      ocrEnabled: false,\n      outputFormat: \"text\",\n      preciseBoundingBox: false,\n    };\n    const liteparse = new LiteParse(config);\n    expect(liteparse.getConfig().preciseBoundingBox).toBeFalsy();\n    const result = await liteparse.parse(\"/tmp/test.docx\");\n    console.log(result.pages.at(0)!.boundingBoxes);\n    expect(\n      result.pages.filter((page) => {\n        return typeof page.boundingBoxes != \"undefined\";\n      }).length\n    ).toBe(0);\n  });\n});\n\ndescribe(\"test screenshot\", () => {\n  it(\"test screenshot with all pages\", async () => {\n    const config: Partial<LiteParseConfig> = { ocrEnabled: false, outputFormat: \"text\" };\n    const liteparse = new LiteParse(config);\n    const results = await liteparse.screenshot(\"/tmp/test.docx\");\n    expect(results.length).toBe(5);\n    expect(results).toStrictEqual(mockScreenshotResults);\n  });\n  it(\"test screenshot with selected pages\", async () => {\n    const config: Partial<LiteParseConfig> = { ocrEnabled: false, outputFormat: \"text\" };\n    const liteparse = new LiteParse(config);\n    const results = await liteparse.screenshot(\"/tmp/test.docx\", [1, 3, 4]);\n    expect(results.length).toBe(3);\n    expect(results).toStrictEqual([\n      mockScreenshotResults[0],\n      mockScreenshotResults[2],\n      mockScreenshotResults[3],\n    ]);\n  });\n});\n"
  },
  {
    "path": "src/core/parser.ts",
    "content": "import pLimit from \"p-limit\";\nimport {\n  LiteParseConfig,\n  LiteParseInput,\n  ParseResult,\n  ScreenshotResult,\n  TextItem,\n} from \"./types.js\";\nimport { mergeConfig } from \"./config.js\";\nimport { PdfEngine, PdfDocument, PageData } from \"../engines/pdf/interface.js\";\nimport { PdfJsEngine } from \"../engines/pdf/pdfjs.js\";\nimport { PdfiumRenderer } from \"../engines/pdf/pdfium-renderer.js\";\nimport { OcrEngine } from \"../engines/ocr/interface.js\";\nimport { TesseractEngine } from \"../engines/ocr/tesseract.js\";\nimport { HttpOcrEngine } from \"../engines/ocr/http-simple.js\";\nimport { projectPagesToGrid } from \"../processing/grid.js\";\nimport { buildBoundingBoxes } from \"../processing/bbox.js\";\nimport { formatJSON } from \"../output/json.js\";\nimport {\n  convertToPdf,\n  convertBufferToPdf,\n  cleanupConversionFiles,\n  guessExtensionFromBuffer,\n} from \"../conversion/convertToPdf.js\";\nimport { cleanOcrTableArtifacts } from \"../processing/textUtils.js\";\n\n/**\n * Main document parser class. Handles PDF parsing, OCR, format conversion,\n * and screenshot generation.\n *\n * @example Basic text extraction\n * ```typescript\n * import { LiteParse } from \"@llamaindex/liteparse\";\n *\n * const parser = new LiteParse();\n * const result = await parser.parse(\"document.pdf\");\n * console.log(result.text);\n * ```\n *\n * @example JSON output with bounding boxes\n * ```typescript\n * const parser = new LiteParse({ outputFormat: \"json\", dpi: 300 });\n * const result = await parser.parse(\"document.pdf\");\n * for (const page of result.json.pages) {\n *   console.log(`Page ${page.page}: ${page.boundingBoxes.length} bounding boxes`);\n * }\n * ```\n *\n * @example Using an HTTP OCR server\n * ```typescript\n * const parser = new LiteParse({\n *   ocrServerUrl: \"http://localhost:8828/ocr\",\n *   ocrLanguage: \"en\",\n * });\n * const result = await parser.parse(\"scanned-document.pdf\");\n * ```\n */\nexport class LiteParse {\n  private config: LiteParseConfig;\n  private pdfEngine: PdfEngine;\n  private ocrEngine?: OcrEngine;\n\n  /**\n   * Create a new LiteParse instance.\n   *\n   * @param userConfig - Partial configuration to override defaults. See {@link LiteParseConfig} for all options.\n   */\n  constructor(userConfig: Partial<LiteParseConfig> = {}) {\n    // Merge user config with defaults\n    this.config = mergeConfig(userConfig);\n\n    // Initialize PDF engine\n    this.pdfEngine = new PdfJsEngine();\n\n    // Initialize OCR engine\n    // Auto-detect: use HTTP OCR if URL provided, otherwise use Tesseract\n    if (this.config.ocrEnabled) {\n      if (this.config.ocrServerUrl) {\n        this.ocrEngine = new HttpOcrEngine(this.config.ocrServerUrl);\n      } else {\n        this.ocrEngine = new TesseractEngine(this.config.numWorkers, this.config.tessdataPath);\n      }\n    }\n  }\n\n  /**\n   * Parse a document and return the extracted text, page data, and optionally structured JSON.\n   *\n   * Supports PDFs natively. Non-PDF formats (DOCX, XLSX, images, etc.) are automatically\n   * converted to PDF before parsing if the required system tools are installed.\n   *\n   * @param input - A file path, `Buffer`, or `Uint8Array` containing document bytes.\n   *   When given raw bytes, PDF data is parsed directly with zero disk I/O.\n   *   Non-PDF bytes are written to a temp file for format conversion.\n   * @param quiet - If `true`, suppresses progress logging to stderr.\n   * @returns Parsed document data including text, per-page info, and optional JSON.\n   *\n   * @throws Error if the file cannot be found, converted, or parsed.\n   */\n  async parse(input: LiteParseInput, quiet = false): Promise<ParseResult> {\n    const log = (msg: string) => {\n      if (!quiet) console.error(msg); // Progress goes to stderr\n    };\n\n    let doc: PdfDocument;\n    let needsCleanup = false;\n    let cleanupPath: string | undefined;\n\n    if (typeof input === \"string\") {\n      log(`Processing file: ${input}`);\n      const conversionResult = await convertToPdf(input, this.config.password);\n\n      if (\"code\" in conversionResult) {\n        throw new Error(`Conversion failed: ${conversionResult.message}`);\n      }\n\n      if (\"content\" in conversionResult) {\n        log(`File is a text-based format. Returning content directly.`);\n        return { pages: [], text: conversionResult.content };\n      }\n\n      const pdfPath = conversionResult.pdfPath;\n      needsCleanup = pdfPath !== input;\n      if (needsCleanup) {\n        cleanupPath = pdfPath;\n        log(`Converted ${conversionResult.originalExtension} to PDF`);\n      }\n\n      doc = await this.pdfEngine.loadDocument(pdfPath, this.config.password);\n    } else {\n      log(`Processing buffer input (${input.byteLength} bytes)`);\n      const ext = await guessExtensionFromBuffer(input);\n\n      if (ext === \".pdf\") {\n        // Zero-disk path: pass bytes directly to the PDF engine\n        const data = input instanceof Uint8Array ? input : new Uint8Array(input);\n        doc = await this.pdfEngine.loadDocument(data, this.config.password);\n      } else {\n        // Non-PDF buffer: write to temp file for conversion\n        const conversionResult = await convertBufferToPdf(input, this.config.password);\n\n        if (\"code\" in conversionResult) {\n          throw new Error(`Conversion failed: ${conversionResult.message}`);\n        }\n\n        if (\"content\" in conversionResult) {\n          log(`Buffer is a text-based format. Returning content directly.`);\n          return { pages: [], text: conversionResult.content };\n        }\n\n        needsCleanup = true;\n        cleanupPath = conversionResult.pdfPath;\n        log(`Converted ${conversionResult.originalExtension} buffer to PDF`);\n        doc = await this.pdfEngine.loadDocument(conversionResult.pdfPath, this.config.password);\n      }\n    }\n\n    log(`Loaded PDF with ${doc.numPages} pages`);\n\n    try {\n      // Extract pages\n      const pages = await this.pdfEngine.extractAllPages(\n        doc,\n        this.config.maxPages,\n        this.config.targetPages,\n        { extractImages: this.config.ocrEnabled }\n      );\n\n      // run BEFORE grid projection\n      if (this.ocrEngine) {\n        await this.runOCR(doc, pages, log);\n      }\n\n      // Process pages with complete grid projection (after OCR)\n      const processedPages = await projectPagesToGrid(pages, this.config);\n\n      // Build bounding boxes if enabled\n      if (this.config.preciseBoundingBox) {\n        for (const page of processedPages) {\n          page.boundingBoxes = buildBoundingBoxes(page.textItems);\n        }\n      }\n\n      // Build final text\n      const fullText = processedPages.map((p) => p.text).join(\"\\n\\n\");\n\n      const result: ParseResult = {\n        pages: processedPages,\n        text: fullText,\n      };\n\n      // Format based on output format\n      switch (this.config.outputFormat) {\n        case \"json\":\n          result.json = JSON.parse(formatJSON(result));\n          break;\n        case \"text\":\n          // Already in text format\n          break;\n      }\n\n      return result;\n    } finally {\n      // Always release resources, even if processing throws\n      await this.pdfEngine.close(doc);\n\n      if (this.ocrEngine && \"terminate\" in this.ocrEngine) {\n        await (this.ocrEngine as TesseractEngine).terminate();\n      }\n\n      if (needsCleanup && cleanupPath) {\n        await cleanupConversionFiles(cleanupPath);\n      }\n    }\n  }\n\n  /**\n   * Generate screenshots of PDF pages as image buffers.\n   *\n   * Uses PDFium for high-quality rendering. Each page is returned as a\n   * {@link ScreenshotResult} with the raw image buffer and dimensions.\n   *\n   * Supports PDFs natively. Non-PDF formats (DOCX, XLSX, images, etc.) are automatically\n   * converted to PDF before rendering if the required system tools are installed.\n   * Text-based formats (TXT, CSV, etc.) cannot be screenshotted and will throw an error.\n   *\n   * @param input - A file path, `Buffer`, or `Uint8Array` containing document bytes.\n   * @param pageNumbers - 1-indexed page numbers to screenshot. If omitted, all pages are rendered.\n   * @param quiet - If `true`, suppresses progress logging to stderr.\n   * @returns Array of screenshot results, one per rendered page.\n   *\n   * @throws Error if the input is a text-based format that cannot be rendered.\n   * @throws Error if the file cannot be found, converted, or rendered.\n   */\n  async screenshot(\n    input: LiteParseInput,\n    pageNumbers?: number[],\n    quiet = false\n  ): Promise<ScreenshotResult[]> {\n    const log = (msg: string) => {\n      if (!quiet) console.error(msg); // Progress goes to stderr\n    };\n\n    log(`Generating screenshots for: ${typeof input === \"string\" ? input : \"<buffer>\"}`);\n\n    let doc: PdfDocument;\n    let pdfInput: string | Uint8Array;\n    let needsCleanup = false;\n    let cleanupPath: string | undefined;\n\n    if (typeof input === \"string\") {\n      const conversionResult = await convertToPdf(input, this.config.password);\n\n      if (\"code\" in conversionResult) {\n        throw new Error(`Conversion failed: ${conversionResult.message}`);\n      }\n\n      if (\"content\" in conversionResult) {\n        throw new Error(`Cannot screenshot text-based format. Convert to PDF first.`);\n      }\n\n      const pdfPath = conversionResult.pdfPath;\n      needsCleanup = pdfPath !== input;\n      if (needsCleanup) {\n        cleanupPath = pdfPath;\n        log(`Converted ${conversionResult.originalExtension} to PDF`);\n      }\n\n      doc = await this.pdfEngine.loadDocument(pdfPath, this.config.password);\n      pdfInput = pdfPath;\n    } else {\n      const ext = await guessExtensionFromBuffer(input);\n\n      if (ext === \".pdf\") {\n        const data = input instanceof Uint8Array ? input : new Uint8Array(input);\n        doc = await this.pdfEngine.loadDocument(data, this.config.password);\n        pdfInput = data;\n      } else {\n        const conversionResult = await convertBufferToPdf(input, this.config.password);\n\n        if (\"code\" in conversionResult) {\n          throw new Error(`Conversion failed: ${conversionResult.message}`);\n        }\n\n        if (\"content\" in conversionResult) {\n          throw new Error(`Cannot screenshot text-based format. Convert to PDF first.`);\n        }\n\n        needsCleanup = true;\n        cleanupPath = conversionResult.pdfPath;\n        log(`Converted ${conversionResult.originalExtension} buffer to PDF`);\n        doc = await this.pdfEngine.loadDocument(conversionResult.pdfPath, this.config.password);\n        pdfInput = conversionResult.pdfPath;\n      }\n    }\n\n    const totalPages = doc.numPages;\n    const results: ScreenshotResult[] = [];\n    const pages = pageNumbers || Array.from({ length: totalPages }, (_, i) => i + 1);\n\n    const renderer = new PdfiumRenderer();\n    await renderer.loadDocument(pdfInput, this.config.password);\n\n    try {\n      for (const pageNum of pages) {\n        if (pageNum < 1 || pageNum > totalPages) {\n          console.error(`Skipping invalid page number: ${pageNum}`);\n          continue;\n        }\n\n        log(`Rendering page ${pageNum}...`);\n        const imageBuffer = await renderer.renderPageToBuffer(pdfInput, pageNum, this.config.dpi);\n\n        const pageData = await this.pdfEngine.extractPage(doc, pageNum, { extractImages: false });\n\n        results.push({\n          pageNum,\n          width: pageData.width,\n          height: pageData.height,\n          imageBuffer,\n        });\n      }\n    } finally {\n      await renderer.close();\n      await this.pdfEngine.close(doc);\n\n      if (needsCleanup && cleanupPath) {\n        await cleanupConversionFiles(cleanupPath);\n      }\n    }\n\n    log(`Generated ${results.length} screenshots`);\n    return results;\n  }\n\n  /**\n   * Run OCR on pages that need it (in parallel with concurrency limit)\n   */\n  private async runOCR(\n    doc: PdfDocument,\n    pages: PageData[],\n    log: (msg: string) => void\n  ): Promise<void> {\n    if (!this.ocrEngine) return;\n\n    log(`Running OCR on pages (concurrency: ${this.config.numWorkers})...`);\n\n    const limit = pLimit(this.config.numWorkers);\n\n    await Promise.all(pages.map((page) => limit(() => this.processPageOcr(doc, page, log))));\n  }\n\n  /**\n   * Process OCR for a single page\n   */\n  private async processPageOcr(\n    doc: PdfDocument,\n    page: PageData,\n    log: (msg: string) => void\n  ): Promise<void> {\n    if (!this.ocrEngine) return;\n\n    // Check if page has very little text (indicating need for OCR)\n    const textLength = page.textItems.reduce(\n      (sum: number, item: TextItem) => sum + item.str.length,\n      0\n    );\n\n    // Determine if OCR is needed and what mode\n    const hasGarbledRegions = page.garbledTextRegions && page.garbledTextRegions.length > 0;\n    const needsFullOcr = textLength < 100 || page.images.length > 0;\n\n    if (!needsFullOcr && !hasGarbledRegions) {\n      return;\n    }\n\n    try {\n      // Render page as image buffer\n      const imageBuffer = await this.pdfEngine.renderPageImage(\n        doc,\n        page.pageNum,\n        this.config.dpi,\n        this.config.password\n      );\n\n      // Run OCR directly on the buffer (no temp file needed)\n      log(`  OCR on page ${page.pageNum}...`);\n      const ocrResults = await this.ocrEngine.recognize(imageBuffer, {\n        language: this.config.ocrLanguage,\n        correctRotation: true,\n      });\n\n      // Convert OCR results to text items and add to page\n      if (ocrResults.length > 0) {\n        // Scale factor to convert from OCR pixels to PDF points\n        // OCR operates at config.dpi, PDF uses 72 points per inch (PDF spec constant)\n        const scaleFactor = 72 / this.config.dpi;\n\n        // Helper to check if an OCR result overlaps with garbled regions\n        const overlapsGarbledRegion = (ocrBbox: number[]): boolean => {\n          if (!page.garbledTextRegions) return false;\n\n          const ocrX = ocrBbox[0] * scaleFactor;\n          const ocrY = ocrBbox[1] * scaleFactor;\n          const ocrW = (ocrBbox[2] - ocrBbox[0]) * scaleFactor;\n          const ocrH = (ocrBbox[3] - ocrBbox[1]) * scaleFactor;\n\n          // Check overlap with any garbled region (with some tolerance)\n          const tolerance = 5; // PDF points\n          for (const region of page.garbledTextRegions) {\n            const overlapX =\n              ocrX < region.x + region.width + tolerance && ocrX + ocrW > region.x - tolerance;\n            const overlapY =\n              ocrY < region.y + region.height + tolerance && ocrY + ocrH > region.y - tolerance;\n            if (overlapX && overlapY) {\n              return true;\n            }\n          }\n          return false;\n        };\n\n        // Helper to check if an OCR result spatially overlaps with existing PDF text\n        // This prevents duplicating text that PDF already extracted correctly\n        const overlapsExistingText = (ocrBbox: number[]): boolean => {\n          const ocrX = ocrBbox[0] * scaleFactor;\n          const ocrY = ocrBbox[1] * scaleFactor;\n          const ocrW = (ocrBbox[2] - ocrBbox[0]) * scaleFactor;\n          const ocrH = (ocrBbox[3] - ocrBbox[1]) * scaleFactor;\n\n          const tolerance = 2; // PDF points - tighter tolerance for existing text\n          for (const item of page.textItems) {\n            const itemRight = item.x + (item.width || item.w || 0);\n            const itemBottom = item.y + (item.height || item.h || 0);\n\n            const overlapX = ocrX < itemRight + tolerance && ocrX + ocrW > item.x - tolerance;\n            const overlapY = ocrY < itemBottom + tolerance && ocrY + ocrH > item.y - tolerance;\n\n            if (overlapX && overlapY) {\n              return true;\n            }\n          }\n          return false;\n        };\n\n        const ocrTextItems: TextItem[] = ocrResults\n          .filter((r) => r.confidence > 0.1) // Filter low confidence\n          .filter((r) => {\n            // For targeted OCR (garbled regions only), only include results that overlap\n            if (hasGarbledRegions && !needsFullOcr) {\n              return overlapsGarbledRegion(r.bbox);\n            }\n            // For full OCR, include all results\n            return true;\n          })\n          .filter((r) => {\n            // Skip OCR results that spatially overlap with existing PDF text\n            // This prevents duplicating text that PDF already extracted correctly\n            return !overlapsExistingText(r.bbox);\n          })\n          .map((r) => {\n            // Clean OCR artifacts from table border misreads\n            const cleanedText = cleanOcrTableArtifacts(r.text);\n            return {\n              str: cleanedText,\n              x: r.bbox[0] * scaleFactor,\n              y: r.bbox[1] * scaleFactor,\n              width: (r.bbox[2] - r.bbox[0]) * scaleFactor,\n              height: (r.bbox[3] - r.bbox[1]) * scaleFactor,\n              w: (r.bbox[2] - r.bbox[0]) * scaleFactor,\n              h: (r.bbox[3] - r.bbox[1]) * scaleFactor,\n              fontName: \"OCR\",\n              fontSize: (r.bbox[3] - r.bbox[1]) * scaleFactor,\n              confidence: Math.round(r.confidence * 1000) / 1000,\n            };\n          })\n          .filter((item) => item.str.length > 0); // Skip items that became empty after cleaning\n\n        // Add OCR text items directly to page textItems\n        page.textItems.push(...ocrTextItems);\n        log(`  Found ${ocrTextItems.length} text items from OCR on page ${page.pageNum}`);\n      }\n    } catch (error) {\n      log(`  OCR failed for page ${page.pageNum}: ${error}`);\n    }\n  }\n\n  /**\n   * Get a copy of the current configuration, including defaults merged with user overrides.\n   *\n   * @returns A shallow copy of the active {@link LiteParseConfig}.\n   */\n  getConfig(): LiteParseConfig {\n    return { ...this.config };\n  }\n}\n"
  },
  {
    "path": "src/core/types.ts",
    "content": "/**\n * Supported output formats for parsed documents.\n *\n * - `\"json\"` — Structured JSON with per-page text items, bounding boxes, and metadata.\n * - `\"text\"` — Plain text with spatial layout preserved.\n */\nimport type { GridDebugConfig } from \"../processing/gridDebugLogger.js\";\n\nexport type OutputFormat = \"json\" | \"text\";\n\n/**\n * Accepted input types for {@link LiteParse.parse} and {@link LiteParse.screenshot}.\n *\n * - `string` — A file path to a document on disk.\n * - `Buffer | Uint8Array` — Raw file bytes (PDF bytes go straight to the parser with zero disk I/O;\n *   non-PDF bytes are written to a temp file for format conversion).\n */\nexport type LiteParseInput = string | Buffer | Uint8Array;\n\n/**\n * Configuration options for the {@link LiteParse} parser.\n *\n * All fields have sensible defaults. Pass a `Partial<LiteParseConfig>` to the\n * constructor to override only the options you need.\n *\n * @example\n * ```typescript\n * const parser = new LiteParse({\n *   ocrEnabled: true,\n *   ocrLanguage: \"fra\",\n *   dpi: 300,\n *   outputFormat: \"json\",\n * });\n * ```\n */\nexport interface LiteParseConfig {\n  /**\n   * OCR language code(s). Uses ISO 639-3 codes for Tesseract (e.g., `\"eng\"`, `\"fra\"`)\n   * or ISO 639-1 for HTTP OCR servers (e.g., `\"en\"`, `\"fr\"`).\n   *\n   * @defaultValue `\"en\"`\n   */\n  ocrLanguage: string | string[];\n\n  /**\n   * Whether to run OCR on pages with little or no native text.\n   * When enabled, LiteParse selectively OCRs only images and text-sparse regions.\n   *\n   * @defaultValue `true`\n   */\n  ocrEnabled: boolean;\n\n  /**\n   * URL of an HTTP OCR server implementing the LiteParse OCR API.\n   * If not provided, the built-in Tesseract.js engine is used.\n   *\n   * @see {@link https://github.com/run-llama/liteparse/blob/main/OCR_API_SPEC.md | OCR API Specification}\n   */\n  ocrServerUrl?: string;\n\n  /**\n   * Path to a directory containing Tesseract `.traineddata` files.\n   * Used as both the language data source and cache directory for Tesseract.js.\n   *\n   * If not set, falls back to the `TESSDATA_PREFIX` environment variable.\n   * If neither is set, Tesseract.js downloads data from cdn.jsdelivr.net.\n   *\n   * @example `/opt/tessdata`\n   */\n  tessdataPath?: string;\n\n  /**\n   * Number of pages to OCR in parallel. Higher values use more memory but\n   * process faster on multi-core machines.\n   *\n   * @defaultValue CPU cores - 1 (minimum 1)\n   */\n  numWorkers: number;\n\n  /**\n   * Maximum number of pages to parse from the document.\n   *\n   * @defaultValue `1000`\n   */\n  maxPages: number;\n\n  /**\n   * Specific pages to parse, as a comma-separated string of page numbers and ranges.\n   *\n   * @example `\"1-5,10,15-20\"`\n   */\n  targetPages?: string;\n\n  /**\n   * DPI (dots per inch) for rendering pages to images. Higher values improve\n   * OCR accuracy but increase processing time and memory usage.\n   *\n   * @defaultValue `150`\n   */\n  dpi: number;\n\n  /**\n   * Output format for parsed results.\n   *\n   * @defaultValue `\"json\"`\n   */\n  outputFormat: OutputFormat;\n\n  /**\n   * Calculate precise bounding boxes for each text line. Disable for faster\n   * parsing when bounding boxes aren't needed.\n   *\n   * @deprecated Controls the deprecated `boundingBoxes` output. Will be removed in v2.0.\n   * Text item coordinates (`x`, `y`, `width`, `height`) are always present regardless.\n   *\n   * @defaultValue `true`\n   */\n  preciseBoundingBox: boolean;\n\n  /**\n   * Preserve very small text that would normally be filtered out.\n   *\n   * @defaultValue `false`\n   */\n  preserveVerySmallText: boolean;\n\n  /**\n   * Maintain consistent text alignment across page boundaries.\n   *\n   * @defaultValue `false`\n   */\n  preserveLayoutAlignmentAcrossPages: boolean;\n\n  /**\n   * Password for opening encrypted/protected documents.\n   * Used for password-protected PDFs and office documents.\n   *\n   * @defaultValue `undefined`\n   */\n  password?: string;\n\n  /**\n   * Debug configuration for grid projection. When enabled, logs detailed\n   * information about how text elements are snapped, anchored, and projected.\n   * Can also generate visual PNG overlays of the projection.\n   *\n   * @example\n   * ```typescript\n   * const parser = new LiteParse({\n   *   debug: {\n   *     enabled: true,\n   *     textFilter: [\"Total\", \"Revenue\"],\n   *     pageFilter: 2,\n   *     visualize: true,\n   *     visualizePath: \"./debug-output\",\n   *   }\n   * });\n   * ```\n   */\n  debug?: GridDebugConfig;\n}\n\n/**\n * An individual text element extracted from a page, with position, size, and font metadata.\n *\n * Coordinates use the PDF coordinate system where the origin is at the top-left\n * of the page, x increases to the right, and y increases downward.\n */\nexport interface TextItem {\n  /** The text content of this item. */\n  str: string;\n  /** X coordinate of the top-left corner, in PDF points. */\n  x: number;\n  /** Y coordinate of the top-left corner, in PDF points. */\n  y: number;\n  /** Width of the text item in PDF points. */\n  width: number;\n  /** Height of the text item in PDF points. */\n  height: number;\n  /** Alias for {@link TextItem.width | width}. */\n  w: number;\n  /** Alias for {@link TextItem.height | height}. */\n  h: number;\n  /** Font name (e.g., `\"Helvetica\"`, `\"Times-Roman\"`, `\"OCR\"` for OCR-detected text). */\n  fontName?: string;\n  /** Font size in PDF points. */\n  fontSize?: number;\n  /** Rotation angle in degrees. One of `0`, `90`, `180`, or `270`. */\n  r?: number;\n  /** X coordinate after rotation transformation. */\n  rx?: number;\n  /** Y coordinate after rotation transformation. */\n  ry?: number;\n  /** Markup annotations (highlights, underlines, etc.) applied to this text. */\n  markup?: MarkupData;\n  /** @internal Whether this item represents a vertical gap. */\n  vgap?: boolean;\n  /** @internal Whether this is a placeholder item used during layout. */\n  isPlaceholder?: boolean;\n  /** Confidence score from 0.0 to 1.0. Native PDF text defaults to 1.0, OCR text reflects engine confidence. */\n  confidence?: number;\n}\n\n/**\n * Markup annotation data associated with a text item.\n */\nexport interface MarkupData {\n  /** Highlight color (e.g., `\"yellow\"`, `\"#FFFF00\"`), or `undefined` if not highlighted. */\n  highlight?: string;\n  /** Whether the text is underlined. */\n  underline?: boolean;\n  /** Whether the text has a squiggly underline. */\n  squiggly?: boolean;\n  /** Whether the text is struck out. */\n  strikeout?: boolean;\n}\n\nexport interface ProjectionTextBox {\n  str: string;\n  x: number;\n  y: number;\n  w: number;\n  h: number;\n  rx?: number;\n  ry?: number;\n  r?: number;\n  strLength: number;\n  markup?: MarkupData;\n  pageBbox?: Coordinates;\n  vgap?: boolean;\n  isPlaceholder?: boolean;\n  fromOCR?: boolean;\n\n  // Projection metadata\n  snap?: \"left\" | \"right\" | \"center\";\n  leftAnchor?: string;\n  rightAnchor?: string;\n  centerAnchor?: string;\n  isDup?: boolean;\n  rendered?: boolean;\n  isMarginLineNumber?: boolean;\n  shouldSpace?: number;\n  forceUnsnapped?: boolean;\n  rotated?: boolean;\n  d?: number; // Delta for rotation handling\n}\n\n/**\n * A rectangle defined by position and dimensions.\n * @internal\n */\nexport interface Coordinates {\n  x: number;\n  y: number;\n  w: number;\n  h: number;\n}\n\n/**\n * Raw OCR detection result before conversion to {@link TextItem}.\n * @internal\n */\nexport interface OcrData {\n  x: number;\n  y: number;\n  w: number;\n  h: number;\n  /** Confidence score from 0.0 to 1.0. */\n  confidence: number;\n  /** Recognized text. */\n  text: string;\n}\n\n/**\n * An axis-aligned bounding box defined by its top-left and bottom-right corners.\n *\n * All coordinates are in PDF points.\n *\n * @deprecated Use {@link TextItem} coordinates (`x`, `y`, `width`, `height`) instead. Will be removed in v2.0.\n */\nexport interface BoundingBox {\n  /** X coordinate of the top-left corner. */\n  x1: number;\n  /** Y coordinate of the top-left corner. */\n  y1: number;\n  /** X coordinate of the bottom-right corner. */\n  x2: number;\n  /** Y coordinate of the bottom-right corner. */\n  y2: number;\n}\n\n/**\n * Parsed data for a single page of a document.\n */\nexport interface ParsedPage {\n  /** 1-indexed page number. */\n  pageNum: number;\n  /** Page width in PDF points. */\n  width: number;\n  /** Page height in PDF points. */\n  height: number;\n  /** Full text content of the page with spatial layout preserved. */\n  text: string;\n  /** Individual text elements extracted from the page. */\n  textItems: TextItem[];\n  /**\n   * @deprecated Use {@link TextItem} coordinates instead. Will be removed in v2.0.\n   * Present when {@link LiteParseConfig.preciseBoundingBox} is enabled.\n   */\n  boundingBoxes?: BoundingBox[];\n}\n\n/**\n * A text element from the JSON output with position, size, and font metadata.\n */\nexport interface JsonTextItem {\n  /** The text content of this item. */\n  text: string;\n  /** X coordinate of the top-left corner, in PDF points. */\n  x: number;\n  /** Y coordinate of the top-left corner, in PDF points. */\n  y: number;\n  /** Width of the text item in PDF points. */\n  width: number;\n  /** Height of the text item in PDF points. */\n  height: number;\n  /** Font name. */\n  fontName?: string;\n  /** Font size in PDF points. */\n  fontSize?: number;\n  /** The OCR confidence (null if OCR wasn't used) */\n  confidence?: number;\n}\n\n/**\n * Options for {@link searchItems}.\n */\nexport interface SearchItemsOptions {\n  /** Find text items containing this phrase. Matches can span multiple adjacent items. */\n  phrase: string;\n  /**\n   * Whether the search should be case-sensitive.\n   *\n   * @defaultValue `false`\n   */\n  caseSensitive?: boolean;\n}\n\n/**\n * Structured JSON representation of parsed document data.\n * Returned when {@link LiteParseConfig.outputFormat} is `\"json\"`.\n */\nexport interface ParseResultJson {\n  /** Array of page data. */\n  pages: Array<{\n    /** 1-indexed page number. */\n    page: number;\n    /** Page width in PDF points. */\n    width: number;\n    /** Page height in PDF points. */\n    height: number;\n    /** Full text content of the page. */\n    text: string;\n    /** Individual text elements with position and font metadata. */\n    textItems: JsonTextItem[];\n    /**\n     * @deprecated Use `textItems` coordinates instead. Will be removed in v2.0.\n     */\n    boundingBoxes: BoundingBox[];\n  }>;\n}\n\n/**\n * The result of parsing a document with {@link LiteParse.parse}.\n */\nexport interface ParseResult {\n  /** Per-page parsed data. */\n  pages: ParsedPage[];\n  /** Full document text, concatenated from all pages. */\n  text: string;\n  /** Structured JSON data. Present when {@link LiteParseConfig.outputFormat} is `\"json\"`. */\n  json?: ParseResultJson;\n}\n\n/**\n * The result of generating a screenshot with {@link LiteParse.screenshot}.\n */\nexport interface ScreenshotResult {\n  /** 1-indexed page number. */\n  pageNum: number;\n  /** Image width in pixels. */\n  width: number;\n  /** Image height in pixels. */\n  height: number;\n  /** Raw image data as a Node.js Buffer (PNG or JPG). */\n  imageBuffer: Buffer;\n  /** File path if the screenshot was saved to disk. */\n  imagePath?: string;\n}\n"
  },
  {
    "path": "src/engines/README.md",
    "content": "# src/engines/\n\nThe engines module provides pluggable abstractions for PDF parsing and OCR functionality. Each engine type has an interface and one or more implementations.\n\n## Directory Structure\n\n```\nengines/\n├── pdf/                    # PDF parsing engines\n│   ├── interface.ts        # PdfEngine interface and data types\n│   ├── pdfjs.ts           # PDF.js implementation (default)\n│   └── pdfium-renderer.ts # PDFium for high-quality screenshots\n└── ocr/                    # OCR engines\n    ├── interface.ts        # OcrEngine interface\n    ├── tesseract.ts       # Tesseract.js (in-process, zero-setup)\n    └── http-simple.ts     # HTTP client for external OCR servers\n```\n\n## Design Philosophy\n\n**Interface-based abstraction** allows swapping implementations without changing core logic:\n\n1. **PdfEngine** - Defines how PDFs are loaded, pages extracted, and images rendered\n2. **OcrEngine** - Defines how images are OCR'd to extract text\n\nThe `LiteParse` class in `src/core/parser.ts` uses these interfaces, allowing future engines to be added without modifying the orchestrator.\n\n## Adding a New Engine\n\n### New PDF Engine\n1. Implement `PdfEngine` interface in `src/engines/pdf/`\n2. Add initialization logic in `src/core/parser.ts` constructor\n3. Optionally add config option to select the engine\n\n### New OCR Engine\n1. Implement `OcrEngine` interface in `src/engines/ocr/`\n2. Add initialization logic in `src/core/parser.ts` constructor\n3. Update engine auto-detection logic if needed\n\nSee subdirectory READMEs for file-specific documentation.\n"
  },
  {
    "path": "src/engines/ocr/README.md",
    "content": "# src/engines/ocr/\n\nOCR engines for extracting text from images.\n\n## Files\n\n### interface.ts\n**Defines the OcrEngine contract.**\n\n```typescript\ninterface OcrEngine {\n  name: string;\n  recognize(image: string | Buffer, options: OcrOptions): Promise<OcrResult[]>;\n  recognizeBatch(images: (string | Buffer)[], options: OcrOptions): Promise<OcrResult[][]>;\n}\n\ninterface OcrOptions {\n  language: string | string[];\n  correctRotation?: boolean;\n}\n\ninterface OcrResult {\n  text: string;\n  bbox: [number, number, number, number];  // [x1, y1, x2, y2]\n  confidence: number;  // 0-1 scale\n}\n```\n\n---\n\n### tesseract.ts\n**In-process OCR using Tesseract.js - zero setup required.**\n\nThis is the default OCR engine when no `ocrServerUrl` is configured.\n\n**Key Features:**\n- Worker-based processing (runs in background thread)\n- Accepts file paths or `Buffer` input directly (no temp files needed)\n- Language caching (reuses worker for same language)\n- Automatic language code normalization (e.g., `en` → `eng`)\n- Low-confidence filtering (removes results < 30%)\n- Supports offline usage via `TESSDATA_PREFIX` env var or `tessdataPath` config for pre-downloaded `.traineddata` files\n\n**Language Normalization:**\nMaps common ISO 639-1 codes to Tesseract's 3-letter codes:\n- `en` → `eng`, `fr` → `fra`, `de` → `deu`, `es` → `spa`\n- `zh` → `chi_sim`, `zh-tw` → `chi_tra`, `ja` → `jpn`, `ko` → `kor`\n- Unknown codes passed through as-is\n\n**Lifecycle:**\n- `initialize(language)` - Create/recreate worker for language\n- `recognize(image, options)` - OCR single image (accepts file path or Buffer)\n- `recognizeBatch(images, options)` - OCR multiple images sequentially\n- `terminate()` - Clean up worker (called by LiteParse after parsing)\n\n**Design Decisions:**\n- **30% confidence threshold**: Filters noisy OCR results (tesseract.ts:59)\n- **Worker caching**: Avoids expensive reinitialization when language unchanged\n- **Sequential batch processing**: Tesseract.js workers aren't parallelizable\n\n---\n\n### http-simple.ts\n**HTTP client for external OCR servers.**\n\nUsed when `ocrServerUrl` is configured. Allows using more powerful OCR backends (EasyOCR, PaddleOCR, etc.) running as separate services.\n\n**API Specification:**\nServers must conform to `OCR_API_SPEC.md`:\n- **Endpoint**: POST to configured URL\n- **Request**: `multipart/form-data` with `file` (image) and `language` fields\n- **Response**: `{ results: [{ text, bbox: [x1,y1,x2,y2], confidence }] }`\n\n**Features:**\n- 60-second timeout per request\n- Graceful error handling (returns empty array on failure)\n- Detailed error logging for debugging\n\n**Design Decision:**\nSimple sequential processing rather than batching because:\n1. External servers may have their own batching/queuing\n2. Keeps the API simple and predictable\n3. Allows per-image error handling\n\n**Example Servers:**\nSee `ocr/easyocr/` and `ocr/paddleocr/` for reference implementations.\n"
  },
  {
    "path": "src/engines/ocr/http-simple.test.ts",
    "content": "import { vi, describe, it, expect } from \"vitest\";\nimport { PassThrough } from \"stream\";\n\nconst mockStream = new PassThrough();\nconst mockOcrItems = [\n  {\n    text: \"Hello World\",\n    bbox: [0, 0, 100, 20],\n    confidence: 0.99,\n  },\n  {\n    text: \"Some text\",\n    bbox: [0, 25, 100, 45],\n    confidence: 0.95,\n  },\n];\n\nvi.mock(\"fs\", async () => {\n  const actual = await vi.importActual<typeof import(\"fs\")>(\"fs\");\n  return {\n    ...actual,\n    default: {\n      createReadStream: vi.fn(() => {\n        return mockStream;\n      }),\n    },\n  };\n});\n\nvi.mock(\"axios\", async () => {\n  const actual = await vi.importActual<typeof import(\"axios\")>(\"axios\");\n  return {\n    default: {\n      ...actual,\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      post: vi.fn(async (url: string, _formData?: any | undefined, _config?: any | undefined) => {\n        if (url == \"http://localhost:9999\") {\n          throw new actual.AxiosError(\"Endpoint not found\", \"404 Not Found\");\n        } else if (url == \"http://localhost:10000\") {\n          throw new Error(\"Unrecheable server\");\n        } else if (url == \"http://localhost:9998\") {\n          // not an array\n          return {\n            data: { results: mockOcrItems[0] },\n          };\n        }\n        return {\n          data: { results: mockOcrItems },\n        };\n      }),\n    },\n  };\n});\n\nimport { HttpOcrEngine } from \"./http-simple\";\n\ndescribe(\"test OCR simple HTTP server (single image)\", () => {\n  it(\"test server success\", async () => {\n    const server = new HttpOcrEngine(\"http://localhost:8000\");\n    expect(server.name).toBe(\"http-ocr\");\n    const result = await server.recognize(\"cat.png\", { language: \"en\" });\n    expect(result).toStrictEqual(mockOcrItems);\n  });\n\n  it(\"test server axios error\", async () => {\n    const server = new HttpOcrEngine(\"http://localhost:9999\");\n    const result = await server.recognize(\"cat.png\", { language: \"en\" });\n    expect(result.length).toBe(0);\n  });\n\n  it(\"test server generic error\", async () => {\n    const server = new HttpOcrEngine(\"http://localhost:10000\");\n    const result = await server.recognize(\"cat.png\", { language: \"en\" });\n    expect(result.length).toBe(0);\n  });\n\n  it(\"test server malformed response\", async () => {\n    const server = new HttpOcrEngine(\"http://localhost:9998\");\n    const result = await server.recognize(\"cat.png\", { language: \"en\" });\n    expect(result.length).toBe(0);\n  });\n});\n\ndescribe(\"test OCR simple HTTP server (batch)\", () => {\n  it(\"test server success\", async () => {\n    const server = new HttpOcrEngine(\"http://localhost:8000\");\n    const result = await server.recognizeBatch([\"cat.png\", \"dog.png\"], { language: \"en\" });\n    expect(result).toStrictEqual([mockOcrItems, mockOcrItems]);\n  });\n\n  it(\"test server axios error\", async () => {\n    const server = new HttpOcrEngine(\"http://localhost:9999\");\n    const result = await server.recognizeBatch([\"cat.png\", \"dog.png\"], { language: \"en\" });\n    expect(result.length).toBe(2);\n    for (const r of result) {\n      expect(r.length).toBe(0);\n    }\n  });\n\n  it(\"test server generic error\", async () => {\n    const server = new HttpOcrEngine(\"http://localhost:10000\");\n    const result = await server.recognizeBatch([\"cat.png\", \"dog.png\"], { language: \"en\" });\n    expect(result.length).toBe(2);\n    for (const r of result) {\n      expect(r.length).toBe(0);\n    }\n  });\n\n  it(\"test server malformed response\", async () => {\n    const server = new HttpOcrEngine(\"http://localhost:9998\");\n    const result = await server.recognizeBatch([\"cat.png\", \"dog.png\"], { language: \"en\" });\n    expect(result.length).toBe(2);\n    for (const r of result) {\n      expect(r.length).toBe(0);\n    }\n  });\n});\n"
  },
  {
    "path": "src/engines/ocr/http-simple.ts",
    "content": "import axios from \"axios\";\nimport FormData from \"form-data\";\nimport fs from \"fs\";\nimport { OcrEngine, OcrOptions, OcrResult } from \"./interface.js\";\n\ninterface HttpOcrResponseItem {\n  text: string;\n  bbox: [number, number, number, number];\n  confidence: number;\n}\n\n/**\n * HTTP-based OCR engine that conforms to LiteParse OCR API specification.\n *\n * The server must implement the API defined in OCR_API_SPEC.md:\n * - POST /ocr endpoint\n * - Accepts multipart/form-data with 'file' and 'language' fields\n * - Returns JSON: { results: [{ text, bbox: [x1,y1,x2,y2], confidence }] }\n *\n * See ocr/easyocr/ and ocr/paddleocr/ for example server implementations.\n */\nexport class HttpOcrEngine implements OcrEngine {\n  name = \"http-ocr\";\n  private serverUrl: string;\n\n  constructor(serverUrl: string) {\n    this.serverUrl = serverUrl;\n  }\n\n  async recognize(image: string | Buffer, options: OcrOptions): Promise<OcrResult[]> {\n    try {\n      // Prepare request\n      const formData = new FormData();\n      if (typeof image === \"string\") {\n        formData.append(\"file\", fs.createReadStream(image));\n      } else {\n        formData.append(\"file\", image, { filename: \"image.png\", contentType: \"image/png\" });\n      }\n\n      const language = Array.isArray(options.language) ? options.language[0] : options.language;\n      formData.append(\"language\", language);\n\n      // Make HTTP request\n      const response = await axios.post(this.serverUrl, formData, {\n        headers: formData.getHeaders(),\n        timeout: 60000,\n      });\n\n      // Parse response (conforming to OCR_API_SPEC.md)\n      const { results } = response.data;\n\n      if (!Array.isArray(results)) {\n        console.warn(\"OCR server response missing results array:\", response.data);\n        return [];\n      }\n\n      return results.map((item: HttpOcrResponseItem) => ({\n        text: item.text,\n        bbox: item.bbox,\n        confidence: item.confidence,\n      }));\n    } catch (error) {\n      const label = typeof image === \"string\" ? image : \"<buffer>\";\n      if (axios.isAxiosError(error)) {\n        console.error(\n          `OCR HTTP error for ${label}:`,\n          error.response?.status,\n          error.response?.data?.error || error.message\n        );\n      } else {\n        console.error(`OCR error for ${label}:`, error);\n      }\n      return [];\n    }\n  }\n\n  async recognizeBatch(images: (string | Buffer)[], options: OcrOptions): Promise<OcrResult[][]> {\n    const results: OcrResult[][] = [];\n    for (const image of images) {\n      const result = await this.recognize(image, options);\n      results.push(result);\n    }\n    return results;\n  }\n}\n"
  },
  {
    "path": "src/engines/ocr/interface.ts",
    "content": "export interface OcrEngine {\n  name: string;\n  recognize(image: string | Buffer, options: OcrOptions): Promise<OcrResult[]>;\n  recognizeBatch(images: (string | Buffer)[], options: OcrOptions): Promise<OcrResult[][]>;\n}\n\nexport interface OcrOptions {\n  language: string | string[];\n  correctRotation?: boolean;\n}\n\nexport interface OcrResult {\n  text: string;\n  bbox: [number, number, number, number];\n  confidence: number;\n}\n"
  },
  {
    "path": "src/engines/ocr/tesseract.test.ts",
    "content": "import { vi, describe, it, expect } from \"vitest\";\n\n// In tesseract.js v6+, words are nested in blocks → paragraphs → lines → words\nconst mockWords = [\n  {\n    text: \"Hello\",\n    confidence: 95,\n    bbox: { x0: 0, y0: 0, x1: 50, y1: 20 },\n  },\n  {\n    text: \"World\",\n    confidence: 92,\n    bbox: { x0: 60, y0: 0, x1: 120, y1: 20 },\n  },\n];\n\nconst mockTesseractResult = {\n  data: {\n    text: \"Hello World\",\n    blocks: [\n      {\n        paragraphs: [\n          {\n            lines: [\n              {\n                words: mockWords,\n              },\n            ],\n          },\n        ],\n      },\n    ],\n    confidence: 93,\n  },\n};\n\nconst mockResults = mockWords.map((word) => ({\n  text: word.text,\n  bbox: [word.bbox.x0, word.bbox.y0, word.bbox.x1, word.bbox.y1] as [\n    number,\n    number,\n    number,\n    number,\n  ],\n  confidence: word.confidence / 100, // Tesseract returns 0-100, we want 0-1\n}));\n\nconst mockTesseractWorker = {\n  terminate: vi.fn(async () => {}),\n  recognize: vi.fn(async () => {\n    return mockTesseractResult;\n  }),\n};\n\nvi.mock(\"tesseract.js\", async () => {\n  const actual = await vi.importActual<typeof import(\"tesseract.js\")>(\"tesseract.js\");\n  return {\n    ...actual,\n    createWorker: vi.fn(\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      async (language: string, _num: number, options?: { errorHandler?: (arg: any) => void }) => {\n        if (language == \"it\" || language == \"ita\") {\n          return;\n        }\n        if (language == \"offline\" || language == \"fetchfail\") {\n          options?.errorHandler?.(\"TypeError: fetch failed\");\n          throw new Error(\"TypeError: fetch failed\");\n        }\n        return mockTesseractWorker;\n      }\n    ),\n  };\n});\n\nimport { TesseractEngine } from \"./tesseract\";\n\ndescribe(\"test Tesseract OCR (single image)\", () => {\n  it(\"test engine success\", async () => {\n    const engine = new TesseractEngine();\n    expect(engine.name).toBe(\"tesseract\");\n    const result = await engine.recognize(\"cat.png\", { language: \"en\" });\n    expect(result).toStrictEqual(mockResults);\n  });\n\n  it(\"test engine failure (failed to initialize)\", async () => {\n    const engine = new TesseractEngine();\n    expect(engine.name).toBe(\"tesseract\");\n    await expect(engine.recognize(\"cat.png\", { language: \"it\" })).rejects.toThrow(\n      \"Tesseract worker not initialized\"\n    );\n  });\n\n  it(\"test engine failure (fetch failed) returns actionable guidance\", async () => {\n    const engine = new TesseractEngine();\n    await expect(engine.recognize(\"cat.png\", { language: \"offline\" })).rejects.toThrow(\n      'Tesseract failed to download language data for \"offline\"'\n    );\n  });\n});\n\ndescribe(\"test OCR simple HTTP server (batch)\", () => {\n  it(\"test engine success\", async () => {\n    const engine = new TesseractEngine();\n    expect(engine.name).toBe(\"tesseract\");\n    const result = await engine.recognizeBatch([\"cat.png\", \"dog.png\"], { language: \"en\" });\n    expect(result).toStrictEqual([mockResults, mockResults]);\n  });\n\n  it(\"test engine failure (failed to initialize)\", async () => {\n    const engine = new TesseractEngine();\n    expect(engine.name).toBe(\"tesseract\");\n    await expect(engine.recognizeBatch([\"cat.png\", \"dog.png\"], { language: \"it\" })).rejects.toThrow(\n      \"Tesseract worker not initialized\"\n    );\n  });\n});\n"
  },
  {
    "path": "src/engines/ocr/tesseract.ts",
    "content": "import { createWorker, createScheduler, Scheduler, Worker } from \"tesseract.js\";\nimport { OcrEngine, OcrOptions, OcrResult } from \"./interface.js\";\n\nexport class TesseractEngine implements OcrEngine {\n  name = \"tesseract\";\n  private scheduler?: Scheduler;\n  private workers: Worker[] = [];\n  private currentLanguage?: string;\n  private concurrency: number;\n  private tessdataPath?: string;\n\n  constructor(concurrency: number = 4, tessdataPath?: string) {\n    this.concurrency = concurrency;\n    // Use explicit path, then TESSDATA_PREFIX env var, then let tesseract.js default (CDN)\n    this.tessdataPath = tessdataPath || process.env.TESSDATA_PREFIX || undefined;\n  }\n\n  async initialize(language: string = \"eng\"): Promise<void> {\n    if (this.scheduler && this.currentLanguage === language) {\n      return; // Already initialized for this language\n    }\n\n    // Clean up existing scheduler and workers if language changed\n    await this.terminate();\n\n    // Create scheduler\n    this.scheduler = createScheduler();\n\n    // Build worker options for local tessdata support\n    const workerOptions: Record<string, unknown> = {};\n    if (this.tessdataPath) {\n      workerOptions.langPath = this.tessdataPath;\n      workerOptions.cachePath = this.tessdataPath;\n      workerOptions.gzip = false; // Pre-cached files are not gzipped\n    }\n    workerOptions.errorHandler = () => {\n      // Let createWorker reject so LiteParse can convert the failure into\n      // an actionable initialization error instead of crashing the process.\n    };\n\n    // Create worker pool\n    for (let i = 0; i < this.concurrency; i++) {\n      let worker: Worker;\n      try {\n        worker = await createWorker(\n          language,\n          1,\n          Object.keys(workerOptions).length > 0 ? workerOptions : undefined\n        );\n      } catch (error) {\n        // Clean up any workers already created\n        await this.terminate();\n        const message = error instanceof Error ? error.message : String(error);\n\n        // Provide actionable guidance for common failures\n        if (\n          message.includes(\"fetch\") ||\n          message.includes(\"network\") ||\n          message.includes(\"ENOTFOUND\") ||\n          message.includes(\"ERR_INVALID_URL\")\n        ) {\n          throw new Error(\n            `Tesseract failed to download language data for \"${language}\". ` +\n              `This usually means the machine has no internet access. ` +\n              `To fix this, either:\\n` +\n              `  1. Set the TESSDATA_PREFIX env var to a directory containing ${language}.traineddata\\n` +\n              `  2. Use --ocr-server-url to use an external OCR server instead\\n` +\n              `  3. Use --no-ocr to disable OCR entirely`,\n            {\n              cause: error,\n            }\n          );\n        }\n        if (\n          message.includes(\"traineddata\") ||\n          message.includes(\"TESSDATA\") ||\n          message.includes(\"loading language\")\n        ) {\n          throw new Error(\n            `Tesseract failed to load language data for \"${language}\": ${message}\\n` +\n              `Ensure ${language}.traineddata exists in your tessdata directory and set ` +\n              `the TESSDATA_PREFIX env var accordingly.`,\n            {\n              cause: error,\n            }\n          );\n        }\n        throw new Error(`Tesseract OCR initialization failed: ${message}`, { cause: error });\n      }\n      if (!worker) {\n        await this.terminate();\n        throw new Error(\"Tesseract worker not initialized\");\n      }\n      this.workers.push(worker);\n      this.scheduler.addWorker(worker);\n    }\n\n    this.currentLanguage = language;\n  }\n\n  async recognize(image: string | Buffer, options: OcrOptions): Promise<OcrResult[]> {\n    // Handle language - tesseract.js uses language codes like 'eng', 'fra', 'deu'\n    const language = this.normalizeLanguage(\n      Array.isArray(options.language) ? options.language[0] : options.language\n    );\n\n    // Initialize scheduler if needed\n    await this.initialize(language);\n\n    if (!this.scheduler) {\n      throw new Error(\"Tesseract scheduler not initialized\");\n    }\n\n    try {\n      // Recognize text from image using scheduler\n      // tesseract.js accepts string (path/URL) or Buffer/Uint8Array\n      // In tesseract.js v6+, we need to enable blocks output to get word-level data\n      const {\n        data: { blocks },\n      } = await this.scheduler.addJob(\n        \"recognize\",\n        image,\n        options.correctRotation ? { rotateAuto: true } : {},\n        { blocks: true }\n      );\n\n      // Extract words from hierarchical blocks structure: blocks → paragraphs → lines → words\n      const results: OcrResult[] = [];\n      for (const block of blocks || []) {\n        for (const paragraph of block.paragraphs || []) {\n          for (const line of paragraph.lines || []) {\n            for (const word of line.words || []) {\n              results.push({\n                text: word.text,\n                bbox: [word.bbox.x0, word.bbox.y0, word.bbox.x1, word.bbox.y1] as [\n                  number,\n                  number,\n                  number,\n                  number,\n                ],\n                confidence: word.confidence / 100, // Tesseract returns 0-100, we want 0-1\n              });\n            }\n          }\n        }\n      }\n\n      // Filter out low confidence results (below 30%)\n      return results.filter((r) => r.confidence > 0.3);\n    } catch (error) {\n      const label = typeof image === \"string\" ? image : \"<buffer>\";\n      console.error(`\\nTesseract OCR error for ${label}:`, error);\n      return [];\n    }\n  }\n\n  async recognizeBatch(images: (string | Buffer)[], options: OcrOptions): Promise<OcrResult[][]> {\n    // Handle language\n    const language = this.normalizeLanguage(\n      Array.isArray(options.language) ? options.language[0] : options.language\n    );\n\n    // Initialize scheduler if needed\n    await this.initialize(language);\n\n    if (!this.scheduler) {\n      throw new Error(\"Tesseract scheduler not initialized\");\n    }\n\n    // Process all images in parallel - scheduler handles distribution\n    const jobs = images.map((image) => this.recognize(image, options));\n\n    return Promise.all(jobs);\n  }\n\n  async terminate(): Promise<void> {\n    if (this.scheduler) {\n      await this.scheduler.terminate();\n      this.scheduler = undefined;\n    }\n    this.workers = [];\n    this.currentLanguage = undefined;\n  }\n\n  /**\n   * Normalize language codes to Tesseract format\n   * Common mappings: en->eng, fr->fra, de->deu, es->spa, zh->chi_sim, ja->jpn\n   */\n  private normalizeLanguage(lang: string): string {\n    const languageMap: Record<string, string> = {\n      en: \"eng\",\n      fr: \"fra\",\n      de: \"deu\",\n      es: \"spa\",\n      it: \"ita\",\n      pt: \"por\",\n      ru: \"rus\",\n      zh: \"chi_sim\",\n      \"zh-cn\": \"chi_sim\",\n      \"zh-tw\": \"chi_tra\",\n      ja: \"jpn\",\n      ko: \"kor\",\n      ar: \"ara\",\n      hi: \"hin\",\n      th: \"tha\",\n      vi: \"vie\",\n    };\n\n    const normalized = lang.toLowerCase().trim();\n    return languageMap[normalized] || normalized;\n  }\n}\n"
  },
  {
    "path": "src/engines/pdf/README.md",
    "content": "# src/engines/pdf/\n\nPDF parsing engines for loading documents and extracting content.\n\n## Files\n\n### interface.ts\n**Defines the PdfEngine contract and data types.**\n\n**PdfEngine Interface:**\n```typescript\ninterface PdfEngine {\n  name: string;\n  loadDocument(input: string | Uint8Array): Promise<PdfDocument>;\n  extractPage(doc: PdfDocument, pageNum: number): Promise<PageData>;\n  extractAllPages(doc, maxPages?, targetPages?): Promise<PageData[]>;\n  renderPageImage(doc, pageNum, dpi): Promise<Buffer>;\n  close(doc: PdfDocument): Promise<void>;\n}\n```\n\n`loadDocument` accepts either a file path or raw PDF bytes as a `Uint8Array`. When given bytes, the document is loaded with zero disk I/O.\n\n**Key Data Types:**\n- `PdfDocument` - Loaded document with `numPages`, `data` (Uint8Array), `metadata`\n- `PageData` - Extracted page: `pageNum`, `width`, `height`, `textItems`, `images`, `annotations`\n- `Image` - Embedded image with position, dimensions, and optional OCR data\n- `Annotation` - PDF annotation (links, etc.)\n\n---\n\n### pdfjs.ts\n**Default PDF engine using Mozilla's PDF.js library.**\n\n**Key Responsibilities:**\n- Load PDF documents with CMap and font support\n- Extract text items with precise coordinates and font information\n- Handle coordinate transformations (PDF space → viewport space)\n- Parse `targetPages` syntax (e.g., \"1-5,10,15-20\")\n- Delegate screenshot rendering to PDFium for quality\n\n**Coordinate Transformation:**\nPDF uses a bottom-left origin with Y pointing up. PDF.js provides transformation matrices that this code processes using:\n- `multiplyMatrices()` - Combine viewport and item transforms\n- `applyTransformation()` - Apply matrix to points\n- `singularValueDecompose2dScale()` - Extract scale factors via SVD\n- `getRotation()` - Extract rotation angle from matrix\n\n**Text Decoding:**\nHandles special PDF.js markers for problematic (\"buggy\") fonts — fonts whose ToUnicode/encoding maps glyphs to control characters or Private Use Area code points:\n- Our patched PDF.js emits markers in the format `:->|>_<glyphId>_<fontCharCode>@<glyphName>@<|<-:` for buggy font glyphs\n- The glyph name comes from the font's `/Differences` or `/Encoding` dictionary\n- `decodeBuggyFontMarkers()` resolves glyph names to Unicode via the `ADOBE_GLYPH_MAP` (a subset of the Adobe Glyph List)\n- Falls back to ASCII char code for glyphs in range 32-126\n- Handles underscore-separated composite glyph names (e.g., `f_i` → \"fi\")\n- Handles `uniXXXX` glyph name convention\n- Also handles pipe-separated characters: `|a| |b| |c|` → `abc`\n- `stripControlChars()` maps Windows-1252 C1 range (0x80-0x9F) to proper Unicode and decomposes Unicode ligatures (U+FB00-FB06) to plain text\n\n**Garbled Font Detection:**\nSome PDFs have fonts with corrupted or missing ToUnicode mappings, causing PDF.js to output characters mapped to unexpected Unicode code points. The `isGarbledFontOutput()` function detects this by identifying:\n\n| Pattern | Unicode Range | Indicator |\n|---------|---------------|-----------|\n| Private Use Area | U+E000-U+F8FF | Fonts map unmapped glyphs here |\n| Arabic + Latin Extended mix | U+0600-U+08FF + U+0100-U+1EFF | Script mixing in English text |\n| Rare scripts | Syriac, Thaana, NKo, Samaritan | U+0700-U+083F |\n| Specials | U+FFF0-U+FFFF | Replacement chars, invalid markers |\n| Box Drawing/Shapes | U+2500-U+25FF | Shouldn't appear in running text |\n\nWhen garbled text is detected:\n1. The text item is filtered out\n2. Its bounding box is saved to `PageData.garbledTextRegions`\n3. OCR runs on the page, but only OCR results overlapping these regions are used\n4. Spatial deduplication prevents OCR from overwriting good PDF text\n\nThis allows targeted OCR replacement of only the corrupted text while preserving high-quality PDF text extraction elsewhere.\n\n**Design Decisions:**\n- **Stores PDF path and data**: Keeps both the file path (when available) and the raw `Uint8Array` data for PDFium rendering. Buffer input skips file reads entirely.\n- **Filters off-page items**: Removes text with negative coords or beyond page bounds\n- **Zero-size filtering**: Skips text items with 0 width/height\n\n---\n\n### pdfium-renderer.ts\n**High-quality screenshot renderer using native PDFium library.**\n\nUsed for generating page images for OCR and the `screenshot` command. Provides better quality than PDF.js canvas rendering, especially for documents with inline images.\n\n**Key Features:**\n- Native C++ PDFium via `@hyzyla/pdfium` WASM binding\n- Sharp for image processing (PNG output with configurable compression)\n- DPI-based scaling (72 DPI baseline)\n- Lazy initialization (only loads when first needed)\n\n**Methods:**\n- `init()` - Initialize PDFium library (called automatically)\n- `renderPageToBuffer(pdfInput, pageNumber, dpi)` - Render page to PNG buffer. Accepts a file path (`string`), `Buffer`, or `Uint8Array`.\n- `close()` - Cleanup PDFium resources\n\n**Design Decision:**\nSeparate from PdfJsEngine because:\n1. PDFium renders better quality images (important for OCR accuracy)\n2. PDF.js is better for text extraction (mature parsing)\n3. Separation allows independent optimization of each concern\n"
  },
  {
    "path": "src/engines/pdf/interface.ts",
    "content": "import { TextItem } from \"../../core/types.js\";\n\n/** Options for page extraction */\nexport interface ExtractOptions {\n  /** Whether to extract embedded image bounds (needed for OCR). Default: true */\n  extractImages?: boolean;\n}\n\nexport interface PdfEngine {\n  name: string;\n  loadDocument(input: string | Uint8Array, password?: string): Promise<PdfDocument>;\n  extractPage(doc: PdfDocument, pageNum: number, options?: ExtractOptions): Promise<PageData>;\n  extractAllPages(\n    doc: PdfDocument,\n    maxPages?: number,\n    targetPages?: string,\n    options?: ExtractOptions\n  ): Promise<PageData[]>;\n  renderPageImage(\n    doc: PdfDocument,\n    pageNum: number,\n    dpi: number,\n    password?: string\n  ): Promise<Buffer>;\n  close(doc: PdfDocument): Promise<void>;\n}\n\nexport interface PdfDocument {\n  numPages: number;\n  data: Uint8Array;\n  metadata?: unknown;\n}\n\n/** Bounding box region */\nexport interface BoundingBox {\n  x: number;\n  y: number;\n  width: number;\n  height: number;\n}\n\nexport interface PageData {\n  pageNum: number;\n  width: number;\n  height: number;\n  textItems: TextItem[];\n  images: Image[];\n  annotations?: Annotation[];\n  /** Bounding boxes of garbled text that was filtered out (for targeted OCR) */\n  garbledTextRegions?: BoundingBox[];\n}\n\nexport interface Path {\n  type: \"rectangle\" | \"line\" | \"curve\";\n  points: number[][];\n  color?: string;\n  width?: number;\n}\n\nexport interface Image {\n  x: number;\n  y: number;\n  width: number;\n  height: number;\n  data?: Buffer;\n  coords?: { x: number; y: number; w: number; h: number };\n  scaleFactor?: number;\n  originalOrientationAngle?: number;\n  type?: string;\n  ocrRaw?: EasyOcrResultLine[];\n  ocrParsed?: Array<{\n    x: number;\n    y: number;\n    w: number;\n    h: number;\n    confidence: number;\n    text: string;\n  }>;\n}\n\n// OCR result line: [coordinates (4 points with x,y), text, confidence]\nexport type EasyOcrResultLine = [\n  [[number, number], [number, number], [number, number], [number, number]],\n  string,\n  string | number,\n];\n\nexport interface Annotation {\n  type: string;\n  subtype?: string;\n  url?: string;\n  rect: number[];\n}\n"
  },
  {
    "path": "src/engines/pdf/pdfium-renderer.test.ts",
    "content": "import { vi, describe, it, expect, beforeEach } from \"vitest\";\nimport { PdfiumRenderer } from \"./pdfium-renderer\";\n\nconst mockPDFiumPageRender = {\n  width: 612,\n  height: 792,\n  originalWidth: 612,\n  originalHeight: 792,\n  data: new Uint8Array(612 * 792 * 4),\n};\n\nconst mockPdfiumPage = {\n  render: vi.fn(async () => {\n    return mockPDFiumPageRender;\n  }),\n};\n\nconst mockPdfiumDoc = {\n  getPage: vi.fn(() => {\n    return mockPdfiumPage;\n  }),\n  destroy: vi.fn(),\n};\n\nconst mockLoadDocument = vi.fn(async () => mockPdfiumDoc);\n\nconst mockPdfiumLibrary = {\n  loadDocument: mockLoadDocument,\n  close: vi.fn(async () => {}),\n  destroy: vi.fn(),\n};\n\nvi.mock(\"fs\", async () => {\n  const actual = await vi.importActual<typeof import(\"fs\")>(\"fs\");\n  return {\n    ...actual,\n    promises: {\n      readFile: vi.fn(async () => {\n        return Buffer.from(\"mock file content\");\n      }),\n    },\n  };\n});\n\nvi.mock(\"@hyzyla/pdfium\", async () => {\n  const actual = await vi.importActual<typeof import(\"@hyzyla/pdfium\")>(\"@hyzyla/pdfium\");\n  return {\n    ...actual,\n    PDFiumLibrary: vi.fn(\n      class {\n        constructor() {}\n\n        static init() {\n          return mockPdfiumLibrary;\n        }\n\n        loadDocument = mockLoadDocument;\n        close = vi.fn(async () => {});\n        destroy = vi.fn();\n      }\n    ),\n  };\n});\n\nbeforeEach(() => {\n  vi.clearAllMocks();\n  mockLoadDocument.mockImplementation(async () => mockPdfiumDoc);\n});\n\ndescribe(\"test renderPageToBuffer\", () => {\n  it(\"test success\", async () => {\n    const renderer = new PdfiumRenderer();\n    const result = await renderer.renderPageToBuffer(\"test.pdf\", 1);\n    expect(result).toStrictEqual(Buffer.from(mockPDFiumPageRender.data));\n  });\n\n  it(\"test error propagation\", async () => {\n    mockLoadDocument.mockImplementationOnce(async () => {\n      throw new Error(\"loading error\");\n    });\n    const renderer = new PdfiumRenderer();\n    await expect(renderer.renderPageToBuffer(\"test.pdf\", 1)).rejects.toThrow(\"loading error\");\n  });\n});\n\ndescribe(\"document caching\", () => {\n  it(\"loadDocument caches and reuses the document across multiple renderPageToBuffer calls\", async () => {\n    const renderer = new PdfiumRenderer();\n    await renderer.loadDocument(\"test.pdf\");\n\n    expect(mockLoadDocument).toHaveBeenCalledTimes(1);\n\n    await renderer.renderPageToBuffer(\"test.pdf\", 1);\n    await renderer.renderPageToBuffer(\"test.pdf\", 2);\n    await renderer.renderPageToBuffer(\"test.pdf\", 3);\n\n    // loadDocument was only called once (during the explicit loadDocument call),\n    // not again for each renderPageToBuffer\n    expect(mockLoadDocument).toHaveBeenCalledTimes(1);\n    expect(mockPdfiumDoc.destroy).not.toHaveBeenCalled();\n\n    await renderer.close();\n    expect(mockPdfiumDoc.destroy).toHaveBeenCalledTimes(1);\n  });\n\n  it(\"without loadDocument, each call creates and destroys a temporary document\", async () => {\n    const renderer = new PdfiumRenderer();\n\n    await renderer.renderPageToBuffer(\"test.pdf\", 1);\n    await renderer.renderPageToBuffer(\"test.pdf\", 2);\n\n    // Each call loads its own document\n    expect(mockLoadDocument).toHaveBeenCalledTimes(2);\n    // Each call destroys its temporary document\n    expect(mockPdfiumDoc.destroy).toHaveBeenCalledTimes(2);\n  });\n\n  it(\"closeDocument destroys cached document\", async () => {\n    const renderer = new PdfiumRenderer();\n    await renderer.loadDocument(\"test.pdf\");\n\n    expect(mockPdfiumDoc.destroy).not.toHaveBeenCalled();\n    renderer.closeDocument();\n    expect(mockPdfiumDoc.destroy).toHaveBeenCalledTimes(1);\n  });\n\n  it(\"close() also cleans up cached document\", async () => {\n    const renderer = new PdfiumRenderer();\n    await renderer.loadDocument(\"test.pdf\");\n\n    await renderer.close();\n    expect(mockPdfiumDoc.destroy).toHaveBeenCalledTimes(1);\n  });\n});\n"
  },
  {
    "path": "src/engines/pdf/pdfium-renderer.ts",
    "content": "import { PDFiumLibrary, PDFiumDocument, type PDFiumPageRenderOptions } from \"@hyzyla/pdfium\";\nimport sharp from \"sharp\";\nimport { promises as fs } from \"fs\";\n\n/**\n * Minimal interface for PDFium's WASM module internals.\n * These properties are private/protected in @hyzyla/pdfium's typings,\n * but we need direct access for low-level page object bound queries.\n */\ninterface PdfiumWasmModule {\n  _FPDFPageObj_GetBounds?: (\n    objHandle: number,\n    leftPtr: number,\n    bottomPtr: number,\n    rightPtr: number,\n    topPtr: number\n  ) => number;\n  _FPDF_GetPageWidthF: (pagePtr: number) => number;\n  _FPDF_GetPageHeightF: (pagePtr: number) => number;\n  _malloc: (size: number) => number;\n  _free: (ptr: number) => void;\n  HEAPU8: Uint8Array;\n}\n\n/** Minimum image dimension in PDF points to be considered for OCR */\nconst MIN_IMAGE_SIZE_PT = 25;\n/** Images covering more than this fraction of the page are treated as backgrounds */\nconst MAX_IMAGE_PAGE_COVERAGE = 0.9;\n\ninterface PdfiumPageInternal {\n  module: PdfiumWasmModule;\n  pageIdx: number;\n  objects(): Iterable<{ type: string; objectIdx: number }>;\n}\n\n/**\n * PDFium-based PDF screenshot renderer\n * Uses native PDFium library for high-quality, fast screenshots\n */\nexport class PdfiumRenderer {\n  private pdfium: PDFiumLibrary | null = null;\n  private cachedDocument: PDFiumDocument | null = null;\n\n  async init(): Promise<void> {\n    if (!this.pdfium) {\n      this.pdfium = await PDFiumLibrary.init();\n    }\n  }\n\n  /**\n   * Pre-load a PDF document so that subsequent per-page calls\n   * (`renderPageToBuffer`, `extractImageBounds`) reuse it instead\n   * of re-parsing the file on every invocation.\n   */\n  async loadDocument(pdfInput: string | Buffer | Uint8Array, password?: string): Promise<void> {\n    await this.init();\n    this.closeDocument();\n    const pdfBuffer =\n      typeof pdfInput === \"string\" ? await fs.readFile(pdfInput) : Buffer.from(pdfInput);\n    this.cachedDocument = await this.pdfium!.loadDocument(pdfBuffer, password);\n  }\n\n  closeDocument(): void {\n    if (this.cachedDocument) {\n      this.cachedDocument.destroy();\n      this.cachedDocument = null;\n    }\n  }\n\n  private async getOrLoadDocument(\n    pdfInput: string | Buffer | Uint8Array,\n    password?: string\n  ): Promise<{ document: PDFiumDocument; isTemporary: boolean }> {\n    if (this.cachedDocument) {\n      return { document: this.cachedDocument, isTemporary: false };\n    }\n    await this.init();\n    const pdfBuffer =\n      typeof pdfInput === \"string\" ? await fs.readFile(pdfInput) : Buffer.from(pdfInput);\n    const document = await this.pdfium!.loadDocument(pdfBuffer, password);\n    return { document, isTemporary: true };\n  }\n\n  async renderPageToBuffer(\n    pdfInput: string | Buffer | Uint8Array,\n    pageNumber: number,\n    dpi: number = 150,\n    password?: string\n  ): Promise<Buffer> {\n    const { document, isTemporary } = await this.getOrLoadDocument(pdfInput, password);\n\n    try {\n      const page = document.getPage(pageNumber - 1);\n      const scale = dpi / 72;\n\n      const image = await page.render({\n        scale,\n        render: async (options: PDFiumPageRenderOptions) => {\n          return await sharp(options.data, {\n            raw: {\n              width: options.width,\n              height: options.height,\n              channels: 4, // RGBA\n            },\n          })\n            .png({\n              compressionLevel: 6,\n            })\n            .withMetadata({\n              density: dpi,\n            })\n            .toBuffer();\n        },\n      });\n\n      return Buffer.from(image.data);\n    } finally {\n      if (isTemporary) {\n        document.destroy();\n      }\n    }\n  }\n\n  /**\n   * Extract bounding boxes of all embedded images on a page.\n   * Uses PDFium's low-level WASM API to iterate page objects and read image bounds.\n   * Returns coordinates in viewport space (Y-down, origin top-left) in PDF points.\n   */\n  async extractImageBounds(\n    pdfInput: string | Buffer | Uint8Array,\n    pageNumber: number,\n    password?: string\n  ): Promise<Array<{ x: number; y: number; width: number; height: number }>> {\n    const { document, isTemporary } = await this.getOrLoadDocument(pdfInput, password);\n\n    try {\n      const page = document.getPage(pageNumber - 1) as unknown as PdfiumPageInternal;\n      const results: Array<{ x: number; y: number; width: number; height: number }> = [];\n\n      const mod = page.module;\n      const pagePtr = page.pageIdx;\n\n      if (!mod || !mod._FPDFPageObj_GetBounds) {\n        return results;\n      }\n\n      const pageWidth = mod._FPDF_GetPageWidthF(pagePtr);\n      const pageHeight = mod._FPDF_GetPageHeightF(pagePtr);\n\n      for (const obj of page.objects()) {\n        if (obj.type !== \"image\") continue;\n\n        const objHandle = obj.objectIdx;\n        if (!objHandle) continue;\n\n        const ptr = mod._malloc(16);\n        try {\n          const ok = mod._FPDFPageObj_GetBounds(objHandle, ptr, ptr + 4, ptr + 8, ptr + 12);\n          if (!ok) continue;\n\n          const buf = mod.HEAPU8.buffer;\n          const view = new DataView(buf);\n          const left = view.getFloat32(ptr, true);\n          const bottom = view.getFloat32(ptr + 4, true);\n          const right = view.getFloat32(ptr + 8, true);\n          const top = view.getFloat32(ptr + 12, true);\n\n          const w = right - left;\n          const h = top - bottom;\n\n          if (w < MIN_IMAGE_SIZE_PT || h < MIN_IMAGE_SIZE_PT) continue;\n          if (w > pageWidth * MAX_IMAGE_PAGE_COVERAGE && h > pageHeight * MAX_IMAGE_PAGE_COVERAGE)\n            continue;\n\n          results.push({\n            x: left,\n            y: pageHeight - top,\n            width: w,\n            height: h,\n          });\n        } finally {\n          mod._free(ptr);\n        }\n      }\n\n      return results;\n    } finally {\n      if (isTemporary) {\n        document.destroy();\n      }\n    }\n  }\n\n  async close(): Promise<void> {\n    this.closeDocument();\n    if (this.pdfium) {\n      this.pdfium.destroy();\n      this.pdfium = null;\n    }\n  }\n}\n"
  },
  {
    "path": "src/engines/pdf/pdfjs.test.ts",
    "content": "import { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { vi, describe, it, expect } from \"vitest\";\n\nvi.mock(\"node:fs/promises\", async () => {\n  const actual = await vi.importActual<typeof import(\"node:fs/promises\")>(\"node:fs/promises\");\n  return {\n    default: {\n      ...actual,\n      readFile: vi.fn(async () => {\n        return Buffer.from(\"hello world\");\n      }),\n    },\n  };\n});\n\nvi.mock(\"./pdfjsImporter.js\", async () => {\n  const actual = await vi.importActual<typeof import(\"./pdfjsImporter.js\")>(\"./pdfjsImporter.js\");\n  return {\n    ...actual,\n    importPdfJs: vi.fn().mockImplementation(async () => {\n      const __filename = fileURLToPath(import.meta.url);\n      const __dirname = dirname(__filename);\n      // From dist/src/engines/pdf/ we need to go up to dist/src/vendor/pdfjs\n      const PDFJS_DIR = join(__dirname, \"../../vendor/pdfjs\");\n\n      const mockDocument = {\n        getMetadata: vi\n          .fn()\n          .mockResolvedValue({ numPages: 10, size: 1024 * 20, encoding: \"utf-8\" }),\n        numPages: 10,\n      };\n\n      const mockGetDocument = vi.fn().mockReturnValue({\n        promise: Promise.resolve(mockDocument),\n      });\n\n      return { fn: mockGetDocument, dir: PDFJS_DIR };\n    }),\n  };\n});\n\nvi.mock(\"./pdfium-renderer.js\", async () => {\n  const actual = await vi.importActual<typeof import(\"./pdfjsImporter.js\")>(\"./pdfjsImporter.js\");\n  return {\n    ...actual,\n    PdfiumRenderer: vi.fn(\n      class {\n        constructor() {}\n\n        loadDocument = vi.fn().mockResolvedValue(undefined);\n        closeDocument = vi.fn();\n        renderPageToBuffer = vi.fn().mockResolvedValue(Buffer.from(\"this is a page\"));\n        close = vi.fn().mockResolvedValue(undefined);\n      }\n    ),\n  };\n});\n\nimport { PdfJsEngine } from \"./pdfjs.js\";\n\nfunction getTestData() {\n  const mockViewport = {\n    width: 612,\n    height: 792,\n    transform: [1, 0, 0, 1, 0, 0],\n  };\n\n  const mockTextContent = {\n    items: [\n      {\n        str: \"Hello, World!\",\n        transform: [12, 0, 0, 12, 50, 700],\n        width: 100,\n        height: 12,\n        fontName: \"Helvetica\",\n      },\n      {\n        str: \"Second line of text\",\n        transform: [10, 0, 0, 10, 50, 680],\n        width: 150,\n        height: 10,\n        fontName: \"Times-Roman\",\n      },\n    ],\n  };\n  const mockPage = {\n    getViewport: vi.fn().mockReturnValue(mockViewport),\n    getTextContent: vi.fn().mockResolvedValue(mockTextContent),\n    cleanup: vi.fn(async () => {}),\n  };\n  const mockDocument = {\n    getPage: vi.fn().mockResolvedValue(mockPage),\n    numPages: 10,\n  };\n\n  const doc = {\n    numPages: 10,\n    data: new Uint8Array(Buffer.from(\"hello world\")),\n    metadata: { numPages: 10, size: 1024 * 20, encoding: \"utf-8\" },\n    _pdfDocument: mockDocument,\n  };\n\n  return doc;\n}\n\nfunction getExpectedResults() {\n  return [\n    {\n      str: \"Hello, World!\",\n      x: 50,\n      y: 700,\n      width: 100,\n      height: 12,\n      w: 100,\n      h: 12,\n      r: 0,\n      fontName: \"Helvetica\",\n      fontSize: 12,\n      confidence: 1.0,\n    },\n    {\n      str: \"Second line of text\",\n      x: 50,\n      y: 680,\n      width: 150,\n      height: 10,\n      w: 150,\n      h: 10,\n      r: 0,\n      fontName: \"Times-Roman\",\n      fontSize: 10,\n      confidence: 1.0,\n    },\n  ];\n}\n\ndescribe(\"test PdfJS methods\", () => {\n  it(\"test loadDocument\", async () => {\n    const engine = new PdfJsEngine();\n    const result = await engine.loadDocument(\"test.pdf\");\n    expect(result.data).toStrictEqual(new Uint8Array(Buffer.from(\"hello world\")));\n    expect(result.metadata).toBeDefined();\n    expect(\"numPages\" in (result.metadata as object)).toBeTruthy();\n    expect(\"size\" in (result.metadata as object)).toBeTruthy();\n    expect(\"encoding\" in (result.metadata as object)).toBeTruthy();\n    expect(result.numPages).toBe(10);\n  });\n\n  it(\"test extractPage\", async () => {\n    const doc = getTestData();\n    const expectedTextItems = getExpectedResults();\n\n    const engine = new PdfJsEngine();\n    const result = await engine.extractPage(doc, 1);\n    expect(result.pageNum).toBe(1);\n    expect(result.width).toBe(612);\n    expect(result.height).toBe(792);\n    expect(result.images.length).toBe(0);\n    expect(result.annotations?.length).toBe(0);\n    expect(result.textItems).toStrictEqual(expectedTextItems);\n    expect(result.garbledTextRegions).toBeUndefined();\n  });\n\n  it(\"test extractAllPages (all pages)\", async () => {\n    const doc = getTestData();\n    const expectedTextItems = getExpectedResults();\n\n    const engine = new PdfJsEngine();\n    const results = await engine.extractAllPages(doc);\n    expect(results.length).toBe(10);\n    let counter = 1;\n    for (const result of results) {\n      expect(result.pageNum).toBe(counter);\n      expect(result.width).toBe(612);\n      expect(result.height).toBe(792);\n      expect(result.images.length).toBe(0);\n      expect(result.annotations?.length).toBe(0);\n      expect(result.textItems).toStrictEqual(expectedTextItems);\n      expect(result.garbledTextRegions).toBeUndefined();\n      counter++;\n    }\n  });\n\n  it(\"test extractAllPages (with maxPages)\", async () => {\n    const doc = getTestData();\n    const expectedTextItems = getExpectedResults();\n\n    const engine = new PdfJsEngine();\n    const results = await engine.extractAllPages(doc, 5);\n    expect(results.length).toBe(5);\n    let counter = 1;\n    for (const result of results) {\n      expect(result.pageNum).toBe(counter);\n      expect(result.width).toBe(612);\n      expect(result.height).toBe(792);\n      expect(result.images.length).toBe(0);\n      expect(result.annotations?.length).toBe(0);\n      expect(result.textItems).toStrictEqual(expectedTextItems);\n      expect(result.garbledTextRegions).toBeUndefined();\n      counter++;\n    }\n  });\n\n  it(\"test extractAllPages (with targetPages)\", async () => {\n    const doc = getTestData();\n    const expectedTextItems = getExpectedResults();\n    const expectedPages = [1, 2, 3, 5];\n\n    const engine = new PdfJsEngine();\n    const results = await engine.extractAllPages(doc, undefined, \"1,2,3,5\");\n    expect(results.length).toBe(4);\n    for (let i = 0; i < results.length; i++) {\n      expect(results[i].pageNum).toBe(expectedPages[i]);\n      expect(results[i].width).toBe(612);\n      expect(results[i].height).toBe(792);\n      expect(results[i].images.length).toBe(0);\n      expect(results[i].annotations?.length).toBe(0);\n      expect(results[i].textItems).toStrictEqual(expectedTextItems);\n      expect(results[i].garbledTextRegions).toBeUndefined();\n    }\n  });\n\n  it(\"test extractAllPages (with targetPages and maxPages)\", async () => {\n    const doc = getTestData();\n    const expectedTextItems = getExpectedResults();\n    const expectedPages = [1, 2, 3, 5];\n\n    const engine = new PdfJsEngine();\n    const results = await engine.extractAllPages(doc, 4, \"1,2,3,5,8\");\n    expect(results.length).toBe(4);\n    for (let i = 0; i < results.length; i++) {\n      expect(results[i].pageNum).toBe(expectedPages[i]);\n      expect(results[i].width).toBe(612);\n      expect(results[i].height).toBe(792);\n      expect(results[i].images.length).toBe(0);\n      expect(results[i].annotations?.length).toBe(0);\n      expect(results[i].textItems).toStrictEqual(expectedTextItems);\n      expect(results[i].garbledTextRegions).toBeUndefined();\n    }\n  });\n\n  it(\"test renderPageImage\", async () => {\n    const doc = getTestData();\n    const engine = new PdfJsEngine();\n    // ensure current PDF path is set\n    await engine.loadDocument(\"test.pdf\");\n\n    const buf = await engine.renderPageImage(doc, 1, 20);\n    expect(buf).toStrictEqual(Buffer.from(\"this is a page\"));\n  });\n});\n"
  },
  {
    "path": "src/engines/pdf/pdfjs.ts",
    "content": "import fs from \"node:fs/promises\";\nimport {\n  PdfEngine,\n  PdfDocument,\n  PageData,\n  Image,\n  Annotation,\n  BoundingBox,\n  ExtractOptions,\n} from \"./interface.js\";\nimport { TextItem } from \"../../core/types.js\";\nimport { PdfiumRenderer } from \"./pdfium-renderer.js\";\nimport { importPdfJs } from \"./pdfjsImporter.js\";\n\n/** PDF.js internal document type - opaque to our code */\ninterface PdfJsDocument {\n  numPages: number;\n  getPage(pageNum: number): Promise<PdfJsPage>;\n  getMetadata(): Promise<unknown>;\n  destroy(): Promise<void>;\n}\n\n/** PDF.js internal page type */\ninterface PdfJsPage {\n  getViewport(params: { scale: number }): PdfJsViewport;\n  getTextContent(): Promise<PdfJsTextContent>;\n  cleanup(): Promise<void>;\n}\n\n/** PDF.js viewport type */\ninterface PdfJsViewport {\n  width: number;\n  height: number;\n  transform: number[];\n}\n\n/** PDF.js text content type */\ninterface PdfJsTextContent {\n  items: PdfJsTextItem[];\n}\n\n/** PDF.js text item type */\ninterface PdfJsTextItem {\n  str: string;\n  transform: number[];\n  width: number;\n  height: number;\n  fontName?: string;\n}\n\n/** Extended PdfDocument with internal PDF.js document reference */\ninterface PdfJsExtendedDocument extends PdfDocument {\n  _pdfDocument: PdfJsDocument;\n}\n\n// Dynamic import of PDF.js\nconst { fn: getDocument, dir: PDFJS_DIR } = await importPdfJs();\n\nconst CMAP_URL = `${PDFJS_DIR}/cmaps/`;\nconst STANDARD_FONT_DATA_URL = `${PDFJS_DIR}/standard_fonts/`;\nconst CMAP_PACKED = true;\n\n/**\n * Extract rotation angle in degrees from PDF transformation matrix\n * Matrix format: [a, b, c, d, e, f] where rotation is atan2(b, a)\n */\nfunction getRotation(transform: number[]): number {\n  return Math.atan2(transform[1], transform[0]) * (180 / Math.PI);\n}\n\n/**\n * Multiply two transformation matrices\n */\nfunction multiplyMatrices(m1: number[], m2: number[]): number[] {\n  return [\n    m1[0] * m2[0] + m1[2] * m2[1],\n    m1[1] * m2[0] + m1[3] * m2[1],\n    m1[0] * m2[2] + m1[2] * m2[3],\n    m1[1] * m2[2] + m1[3] * m2[3],\n    m1[0] * m2[4] + m1[2] * m2[5] + m1[4],\n    m1[1] * m2[4] + m1[3] * m2[5] + m1[5],\n  ];\n}\n\n/**\n * Apply transformation matrix to a point\n */\nfunction applyTransformation(\n  point: { x: number; y: number },\n  transform: number[]\n): { x: number; y: number } {\n  return {\n    x: point.x * transform[0] + point.y * transform[2] + transform[4],\n    y: point.x * transform[1] + point.y * transform[3] + transform[5],\n  };\n}\n\n// Pre-compiled regex patterns for string decoding\nconst BUGGY_FONT_MARKER_CHECK = \":->|>\";\nconst PIPE_PATTERN_REGEX = /\\s*\\|([^|])\\|\\s*/g;\n\n/**\n * Adobe Glyph List subset: maps standard PostScript glyph names to Unicode characters.\n *\n * When PDF.js detects a \"buggy\" font (one whose ToUnicode/encoding maps glyphs to\n * control characters or PUA code points), it emits markers containing the glyph's\n * original char code AND the glyph name from the font's /Differences or /Encoding\n * dictionary. This map resolves those glyph names to correct Unicode characters.\n *\n * This is a ~200-entry subset of the full Adobe Glyph List (~4,300 entries).\n * The full canonical source is: https://github.com/adobe-type-tools/agl-aglfn\n * (see glyphlist.txt). Our subset covers basic Latin, digits, ligatures, punctuation,\n * typographic characters, Greek, math symbols, and common accented Latin. Glyph names\n * not in this subset fall through to the uniXXXX convention and ASCII-range fallbacks\n * in resolveGlyphName(). Add entries here if a PDF's buggy font uses a standard glyph\n * name that isn't covered and doesn't match those fallbacks.\n */\nconst ADOBE_GLYPH_MAP: Record<string, string> = {\n  // Basic Latin letters\n  A: \"A\",\n  B: \"B\",\n  C: \"C\",\n  D: \"D\",\n  E: \"E\",\n  F: \"F\",\n  G: \"G\",\n  H: \"H\",\n  I: \"I\",\n  J: \"J\",\n  K: \"K\",\n  L: \"L\",\n  M: \"M\",\n  N: \"N\",\n  O: \"O\",\n  P: \"P\",\n  Q: \"Q\",\n  R: \"R\",\n  S: \"S\",\n  T: \"T\",\n  U: \"U\",\n  V: \"V\",\n  W: \"W\",\n  X: \"X\",\n  Y: \"Y\",\n  Z: \"Z\",\n  a: \"a\",\n  b: \"b\",\n  c: \"c\",\n  d: \"d\",\n  e: \"e\",\n  f: \"f\",\n  g: \"g\",\n  h: \"h\",\n  i: \"i\",\n  j: \"j\",\n  k: \"k\",\n  l: \"l\",\n  m: \"m\",\n  n: \"n\",\n  o: \"o\",\n  p: \"p\",\n  q: \"q\",\n  r: \"r\",\n  s: \"s\",\n  t: \"t\",\n  u: \"u\",\n  v: \"v\",\n  w: \"w\",\n  x: \"x\",\n  y: \"y\",\n  z: \"z\",\n  // Digits\n  zero: \"0\",\n  one: \"1\",\n  two: \"2\",\n  three: \"3\",\n  four: \"4\",\n  five: \"5\",\n  six: \"6\",\n  seven: \"7\",\n  eight: \"8\",\n  nine: \"9\",\n  // Ligatures (Unicode presentation forms — decomposed later by stripControlChars)\n  fi: \"\\uFB01\",\n  fl: \"\\uFB02\",\n  ff: \"\\uFB00\",\n  ffi: \"\\uFB03\",\n  ffl: \"\\uFB04\",\n  // Punctuation and symbols\n  space: \" \",\n  period: \".\",\n  comma: \",\",\n  colon: \":\",\n  semicolon: \";\",\n  hyphen: \"-\",\n  minus: \"\\u2212\",\n  slash: \"/\",\n  question: \"?\",\n  dollar: \"$\",\n  parenleft: \"(\",\n  parenright: \")\",\n  asterisk: \"*\",\n  plus: \"+\",\n  equal: \"=\",\n  numbersign: \"#\",\n  percent: \"%\",\n  ampersand: \"&\",\n  at: \"@\",\n  exclam: \"!\",\n  bracketleft: \"[\",\n  bracketright: \"]\",\n  braceleft: \"{\",\n  braceright: \"}\",\n  underscore: \"_\",\n  quotedbl: '\"',\n  quotesingle: \"'\",\n  backslash: \"\\\\\",\n  bar: \"|\",\n  asciitilde: \"~\",\n  asciicircum: \"^\",\n  grave: \"`\",\n  less: \"<\",\n  greater: \">\",\n  // Typographic\n  quoteright: \"\\u2019\",\n  quoteleft: \"\\u2018\",\n  quotedblleft: \"\\u201C\",\n  quotedblright: \"\\u201D\",\n  quotesinglbase: \"\\u201A\",\n  quotedblbase: \"\\u201E\",\n  endash: \"\\u2013\",\n  emdash: \"\\u2014\",\n  bullet: \"\\u2022\",\n  ellipsis: \"\\u2026\",\n  dagger: \"\\u2020\",\n  daggerdbl: \"\\u2021\",\n  guilsinglleft: \"\\u2039\",\n  guilsinglright: \"\\u203A\",\n  guillemotleft: \"\\u00AB\",\n  guillemotright: \"\\u00BB\",\n  trademark: \"\\u2122\",\n  registered: \"\\u00AE\",\n  copyright: \"\\u00A9\",\n  // Greek\n  Alpha: \"\\u0391\",\n  Beta: \"\\u0392\",\n  Gamma: \"\\u0393\",\n  Delta: \"\\u2206\",\n  Epsilon: \"\\u0395\",\n  Zeta: \"\\u0396\",\n  Eta: \"\\u0397\",\n  Theta: \"\\u0398\",\n  Iota: \"\\u0399\",\n  Kappa: \"\\u039A\",\n  Lambda: \"\\u039B\",\n  Mu: \"\\u039C\",\n  Nu: \"\\u039D\",\n  Xi: \"\\u039E\",\n  Omicron: \"\\u039F\",\n  Pi: \"\\u03A0\",\n  Rho: \"\\u03A1\",\n  Sigma: \"\\u03A3\",\n  Tau: \"\\u03A4\",\n  Upsilon: \"\\u03A5\",\n  Phi: \"\\u03A6\",\n  Chi: \"\\u03A7\",\n  Psi: \"\\u03A8\",\n  Omega: \"\\u2126\",\n  alpha: \"\\u03B1\",\n  beta: \"\\u03B2\",\n  gamma: \"\\u03B3\",\n  delta: \"\\u03B4\",\n  epsilon: \"\\u03B5\",\n  zeta: \"\\u03B6\",\n  eta: \"\\u03B7\",\n  theta: \"\\u03B8\",\n  iota: \"\\u03B9\",\n  kappa: \"\\u03BA\",\n  lambda: \"\\u03BB\",\n  mu: \"\\u00B5\",\n  nu: \"\\u03BD\",\n  xi: \"\\u03BE\",\n  omicron: \"\\u03BF\",\n  pi: \"\\u03C0\",\n  rho: \"\\u03C1\",\n  sigma: \"\\u03C3\",\n  tau: \"\\u03C4\",\n  upsilon: \"\\u03C5\",\n  phi: \"\\u03C6\",\n  chi: \"\\u03C7\",\n  psi: \"\\u03C8\",\n  omega: \"\\u03C9\",\n  // Math symbols\n  greaterequal: \"\\u2265\",\n  lessequal: \"\\u2264\",\n  notequal: \"\\u2260\",\n  plusminus: \"\\u00B1\",\n  multiply: \"\\u00D7\",\n  divide: \"\\u00F7\",\n  infinity: \"\\u221E\",\n  summation: \"\\u2211\",\n  integral: \"\\u222B\",\n  partialdiff: \"\\u2202\",\n  radical: \"\\u221A\",\n  approxequal: \"\\u2248\",\n  degree: \"\\u00B0\",\n  // Accented Latin (common)\n  Aacute: \"\\u00C1\",\n  Agrave: \"\\u00C0\",\n  Acircumflex: \"\\u00C2\",\n  Atilde: \"\\u00C3\",\n  Adieresis: \"\\u00C4\",\n  Aring: \"\\u00C5\",\n  Eacute: \"\\u00C9\",\n  Egrave: \"\\u00C8\",\n  Ecircumflex: \"\\u00CA\",\n  Edieresis: \"\\u00CB\",\n  Iacute: \"\\u00CD\",\n  Igrave: \"\\u00CC\",\n  Icircumflex: \"\\u00CE\",\n  Idieresis: \"\\u00CF\",\n  Oacute: \"\\u00D3\",\n  Ograve: \"\\u00D2\",\n  Ocircumflex: \"\\u00D4\",\n  Otilde: \"\\u00D5\",\n  Odieresis: \"\\u00D6\",\n  Uacute: \"\\u00DA\",\n  Ugrave: \"\\u00D9\",\n  Ucircumflex: \"\\u00DB\",\n  Udieresis: \"\\u00DC\",\n  Ntilde: \"\\u00D1\",\n  Ccedilla: \"\\u00C7\",\n  Scaron: \"\\u0160\",\n  Zcaron: \"\\u017D\",\n  aacute: \"\\u00E1\",\n  agrave: \"\\u00E0\",\n  acircumflex: \"\\u00E2\",\n  atilde: \"\\u00E3\",\n  adieresis: \"\\u00E4\",\n  aring: \"\\u00E5\",\n  eacute: \"\\u00E9\",\n  egrave: \"\\u00E8\",\n  ecircumflex: \"\\u00EA\",\n  edieresis: \"\\u00EB\",\n  iacute: \"\\u00ED\",\n  igrave: \"\\u00EC\",\n  icircumflex: \"\\u00EE\",\n  idieresis: \"\\u00EF\",\n  oacute: \"\\u00F3\",\n  ograve: \"\\u00F2\",\n  ocircumflex: \"\\u00F4\",\n  otilde: \"\\u00F5\",\n  odieresis: \"\\u00F6\",\n  uacute: \"\\u00FA\",\n  ugrave: \"\\u00F9\",\n  ucircumflex: \"\\u00FB\",\n  udieresis: \"\\u00FC\",\n  ntilde: \"\\u00F1\",\n  ccedilla: \"\\u00E7\",\n  scaron: \"\\u0161\",\n  zcaron: \"\\u017E\",\n  ydieresis: \"\\u00FF\",\n  // Miscellaneous\n  AE: \"\\u00C6\",\n  ae: \"\\u00E6\",\n  OE: \"\\u0152\",\n  oe: \"\\u0153\",\n  Eth: \"\\u00D0\",\n  eth: \"\\u00F0\",\n  Thorn: \"\\u00DE\",\n  thorn: \"\\u00FE\",\n  germandbls: \"\\u00DF\",\n  dotlessi: \"\\u0131\",\n  section: \"\\u00A7\",\n  paragraph: \"\\u00B6\",\n  currency: \"\\u00A4\",\n  cent: \"\\u00A2\",\n  sterling: \"\\u00A3\",\n  yen: \"\\u00A5\",\n  Euro: \"\\u20AC\",\n  logicalnot: \"\\u00AC\",\n  nbspace: \"\\u00A0\",\n};\n\n/**\n * Resolve a glyph name to its Unicode character using the Adobe Glyph List.\n * Handles standard names, the \"uniXXXX\" convention, and underscore-separated\n * composite names (e.g., \"f_i\" → resolve \"f\" + \"i\" = \"fi\").\n */\nfunction resolveGlyphName(glyphName: string): string | null {\n  if (glyphName in ADOBE_GLYPH_MAP) return ADOBE_GLYPH_MAP[glyphName];\n\n  // Handle \"uniXXXX\" convention (e.g., \"uni00A0\" → U+00A0)\n  if (glyphName.startsWith(\"uni\") && glyphName.length === 7) {\n    const code = parseInt(glyphName.slice(3), 16);\n    if (!isNaN(code) && code > 0) return String.fromCharCode(code);\n  }\n\n  // Handle underscore-separated composite names (e.g., \"f_i\" → \"fi\", \"f_f_i\" → \"ffi\")\n  // Some fonts use this convention instead of standard ligature names\n  if (glyphName.includes(\"_\")) {\n    const parts = glyphName.split(\"_\");\n    const resolved = parts.map((p) => resolveGlyphName(p));\n    if (resolved.every((r) => r !== null)) {\n      return resolved.join(\"\");\n    }\n  }\n\n  return null;\n}\n\n/**\n * Decode buggy font markers emitted by patched PDF.js.\n *\n * Marker format: :->|>_<glyphId>_<fontCharCode>@<glyphName>@<|<-:\n * The glyph name is delimited by @ instead of _ because some fonts use\n * non-standard glyph names containing underscores (e.g., \"f_i\" for \"fi\").\n *\n * Resolution strategy:\n * 1. Use glyph name from font's /Differences or /Encoding dictionary\n * 2. Fall back to glyphId if it's in printable ASCII range (32-126)\n * 3. Drop the character if neither works (better than guessing)\n */\nconst BUGGY_FONT_MARKER_RE = /:->\\|>_(\\d+)_\\d+@([^@]*)@<\\|<-:/g;\n\nfunction decodeBuggyFontMarkers(str: string): string {\n  return str.replace(BUGGY_FONT_MARKER_RE, (_match, glyphIdStr: string, glyphName: string) => {\n    // Priority 1: Resolve via glyph name from font metadata\n    if (glyphName) {\n      const resolved = resolveGlyphName(glyphName);\n      if (resolved) return resolved;\n    }\n\n    // Priority 2: If glyphId is in printable ASCII range, use it directly\n    const glyphId = parseInt(glyphIdStr);\n    if (glyphId >= 32 && glyphId <= 126) {\n      return String.fromCharCode(glyphId);\n    }\n\n    // Priority 3: Drop unresolvable characters\n    return \"\";\n  });\n}\n\n/**\n * Windows-1252 to Unicode mapping for the C1 control range (0x80-0x9F).\n *\n * Many PDFs encode smart quotes, em-dashes, and other typographic characters\n * using Windows-1252 byte values. When PDF.js decodes these without a proper\n * ToUnicode map, the raw byte values end up in the 0x80-0x9F range — which is\n * technically the C1 control character block in Unicode. Rather than stripping\n * them (which loses apostrophes, quotes, dashes, etc.), we map them to their\n * correct Unicode equivalents.\n */\nconst WINDOWS_1252_TO_UNICODE: Record<number, string> = {\n  0x80: \"\\u20AC\", // €\n  0x82: \"\\u201A\", // ‚\n  0x83: \"\\u0192\", // ƒ\n  0x84: \"\\u201E\", // „\n  0x85: \"\\u2026\", // …\n  0x86: \"\\u2020\", // †\n  0x87: \"\\u2021\", // ‡\n  0x88: \"\\u02C6\", // ˆ\n  0x89: \"\\u2030\", // ‰\n  0x8a: \"\\u0160\", // Š\n  0x8b: \"\\u2039\", // ‹\n  0x8c: \"\\u0152\", // Œ\n  0x8e: \"\\u017D\", // Ž\n  0x91: \"\\u2018\", // '\n  0x92: \"\\u2019\", // ' (right single quote / apostrophe)\n  0x93: \"\\u201C\", // \"\n  0x94: \"\\u201D\", // \"\n  0x95: \"\\u2022\", // •\n  0x96: \"\\u2013\", // –\n  0x97: \"\\u2014\", // —\n  0x98: \"\\u02DC\", // ˜\n  0x99: \"\\u2122\", // ™\n  0x9a: \"\\u0161\", // š\n  0x9b: \"\\u203A\", // ›\n  0x9c: \"\\u0153\", // œ\n  0x9e: \"\\u017E\", // ž\n  0x9f: \"\\u0178\", // Ÿ\n};\n\n/**\n * Unicode ligature decomposition map.\n * PDF fonts often use ligature glyphs; decomposing them to plain ASCII\n * ensures the text is searchable and NLP-friendly.\n */\nconst LIGATURE_MAP: Record<string, string> = {\n  \"\\uFB00\": \"ff\",\n  \"\\uFB01\": \"fi\",\n  \"\\uFB02\": \"fl\",\n  \"\\uFB03\": \"ffi\",\n  \"\\uFB04\": \"ffl\",\n  \"\\uFB05\": \"st\",\n  \"\\uFB06\": \"st\",\n};\n\n/**\n * Strip C0 control characters from text (except common whitespace),\n * map C1 control range (0x80-0x9F) to proper Unicode via Windows-1252,\n * and decompose Unicode ligatures to plain text.\n */\nfunction stripControlChars(str: string): string {\n  let result = \"\";\n  for (const char of str) {\n    const code = char.charCodeAt(0);\n\n    // Decompose Unicode ligatures (fi, fl, ff, ffi, ffl, st)\n    if (LIGATURE_MAP[char]) {\n      result += LIGATURE_MAP[char];\n      continue;\n    }\n\n    // Map Windows-1252 C1 range to proper Unicode (smart quotes, em-dashes, etc.)\n    if (code >= 0x80 && code <= 0x9f) {\n      const mapped = WINDOWS_1252_TO_UNICODE[code];\n      if (mapped) {\n        result += mapped;\n      }\n      // Undefined C1 positions (0x81, 0x8D, 0x8F, 0x90) are dropped\n      continue;\n    }\n\n    // Skip C0 controls (except tab, newline, carriage return)\n    if (code >= 0x00 && code <= 0x1f && code !== 0x09 && code !== 0x0a && code !== 0x0d) {\n      continue;\n    }\n\n    result += char;\n  }\n  return result;\n}\n\n/**\n * Detect garbled text from fonts with corrupted ToUnicode mappings.\n *\n * When PDF fonts lack proper ToUnicode maps, PDF.js may output characters\n * mapped to unexpected Unicode code points. Common patterns include:\n *\n * 1. Private Use Area (PUA) characters - fonts often map glyphs here\n * 2. Mix of unrelated scripts (Arabic + Latin Extended in English text)\n * 3. Rare/obscure Unicode blocks appearing in normal text\n * 4. Control characters (when text is predominantly control chars)\n *\n * Returns true if the string appears to be garbled font output.\n */\nfunction isGarbledFontOutput(str: string): boolean {\n  if (str.length < 3) return false;\n\n  let privateUseCount = 0;\n  let arabicCount = 0;\n  let latinExtendedCount = 0;\n  let basicLatinLetterCount = 0;\n  let suspiciousCount = 0; // Other suspicious Unicode ranges\n  let controlCharCount = 0; // C0/C1 control characters\n  let normalCharCount = 0; // Normal printable characters\n\n  for (const char of str) {\n    const code = char.charCodeAt(0);\n\n    // C0 control characters (0x00-0x1F) except common whitespace (tab, newline, carriage return)\n    if (code >= 0x00 && code <= 0x1f && code !== 0x09 && code !== 0x0a && code !== 0x0d) {\n      controlCharCount++;\n    }\n    // C1 range (0x80-0x9F): only count as control chars if NOT a valid Windows-1252 character.\n    // Many PDFs use Windows-1252 encoding for smart quotes, em-dashes, etc.\n    else if (code >= 0x80 && code <= 0x9f) {\n      if (WINDOWS_1252_TO_UNICODE[code]) {\n        normalCharCount++; // Valid Windows-1252 char (smart quote, dash, etc.)\n      } else {\n        controlCharCount++; // Undefined C1 position — likely garbled\n      }\n    }\n    // Private Use Area (U+E000-U+F8FF) - almost always garbled\n    else if (code >= 0xe000 && code <= 0xf8ff) {\n      privateUseCount++;\n    }\n    // Arabic block (0x600-0x6FF) and Arabic Extended (0x750-0x77F, 0x8A0-0x8FF)\n    else if (\n      (code >= 0x600 && code <= 0x6ff) ||\n      (code >= 0x750 && code <= 0x77f) ||\n      (code >= 0x8a0 && code <= 0x8ff)\n    ) {\n      arabicCount++;\n    }\n    // Latin Extended-A (0x100-0x17F), Latin Extended-B (0x180-0x24F),\n    // Latin Extended Additional (0x1E00-0x1EFF)\n    else if ((code >= 0x100 && code <= 0x24f) || (code >= 0x1e00 && code <= 0x1eff)) {\n      latinExtendedCount++;\n    }\n    // Basic Latin letters (a-z, A-Z)\n    else if ((code >= 0x41 && code <= 0x5a) || (code >= 0x61 && code <= 0x7a)) {\n      basicLatinLetterCount++;\n      normalCharCount++;\n    }\n    // Suspicious ranges that rarely appear in normal text:\n    // - Syriac (0x700-0x74F)\n    // - Thaana (0x780-0x7BF)\n    // - NKo (0x7C0-0x7FF)\n    // - Samaritan (0x800-0x83F)\n    // - Specials (0xFFF0-0xFFFF)\n    // - Geometric Shapes (0x25A0-0x25FF) in running text\n    // - Box Drawing (0x2500-0x257F) in running text\n    // - Combining Diacritical Marks alone (0x0300-0x036F)\n    else if (\n      (code >= 0x700 && code <= 0x7ff) || // Syriac, Thaana, NKo\n      (code >= 0x800 && code <= 0x83f) || // Samaritan\n      (code >= 0xfff0 && code <= 0xffff) || // Specials\n      (code >= 0x2500 && code <= 0x25ff) || // Box drawing, geometric shapes\n      (code >= 0x0300 && code <= 0x036f) // Combining marks (suspicious if frequent)\n    ) {\n      suspiciousCount++;\n    }\n    // Normal printable characters (digits, punctuation, common symbols, space)\n    else if ((code >= 0x20 && code <= 0x7e) || code === 0x09 || code === 0x0a || code === 0x0d) {\n      normalCharCount++;\n    }\n  }\n\n  const totalChars = str.length;\n\n  // Text is predominantly control characters - definitely garbled\n  // This catches cases like more_hard_2.pdf where text is entirely control chars\n  if (controlCharCount > 0 && controlCharCount > normalCharCount) {\n    return true;\n  }\n\n  // Private Use Area characters are almost always garbled fonts\n  if (privateUseCount >= 2) {\n    return true;\n  }\n\n  // Mix of Arabic AND Latin Extended is extremely rare in legitimate text\n  if (arabicCount >= 2 && latinExtendedCount >= 2) {\n    return true;\n  }\n\n  // High concentration of suspicious characters\n  if (suspiciousCount >= 3 || suspiciousCount > totalChars * 0.2) {\n    return true;\n  }\n\n  // Text predominantly Latin Extended with very few basic Latin letters\n  // (legitimate Latin-script text would have mostly basic Latin)\n  if (latinExtendedCount > totalChars * 0.3 && basicLatinLetterCount < totalChars * 0.2) {\n    return true;\n  }\n\n  // Mix of Arabic/suspicious with Latin Extended (script mixing)\n  if ((arabicCount >= 1 || suspiciousCount >= 1) && latinExtendedCount >= 3) {\n    return true;\n  }\n\n  return false;\n}\n\nexport class PdfJsEngine implements PdfEngine {\n  name = \"pdfjs\";\n  private pdfiumRenderer: PdfiumRenderer | null = null;\n  private currentPdfPath: string | null = null;\n  private currentPdfData: Uint8Array | null = null;\n\n  async loadDocument(input: string | Uint8Array, password?: string): Promise<PdfDocument> {\n    let data: Uint8Array;\n    if (typeof input === \"string\") {\n      data = new Uint8Array(await fs.readFile(input));\n      this.currentPdfPath = input;\n    } else {\n      // pdf.js requires a plain Uint8Array, not a Buffer subclass\n      data = new Uint8Array(input.buffer, input.byteOffset, input.byteLength);\n      this.currentPdfPath = null;\n    }\n\n    // Store data for buffer-based rendering\n    this.currentPdfData = data;\n\n    const loadingTask = getDocument({\n      data,\n      password,\n      cMapUrl: CMAP_URL,\n      cMapPacked: CMAP_PACKED,\n      standardFontDataUrl: STANDARD_FONT_DATA_URL,\n    });\n\n    let pdfDocument: PdfJsDocument;\n    try {\n      pdfDocument = await loadingTask.promise;\n    } catch (error: unknown) {\n      const message = error instanceof Error ? error.message : String(error);\n      if (message.includes(\"password\") || message.includes(\"Password\")) {\n        if (password) {\n          throw new Error(\n            \"Incorrect password for this PDF. Please check the password and try again.\",\n            { cause: error }\n          );\n        } else {\n          throw new Error(\n            \"This PDF is password-protected. Use --password <password> to provide the document password.\",\n            { cause: error }\n          );\n        }\n      }\n      throw error;\n    }\n\n    const metadata = await pdfDocument.getMetadata();\n\n    return {\n      numPages: pdfDocument.numPages,\n      data,\n      metadata,\n      _pdfDocument: pdfDocument,\n    } as PdfJsExtendedDocument;\n  }\n\n  async extractPage(\n    doc: PdfDocument,\n    pageNum: number,\n    options?: ExtractOptions\n  ): Promise<PageData> {\n    const pdfDocument = (doc as PdfJsExtendedDocument)._pdfDocument;\n    const page = await pdfDocument.getPage(pageNum);\n\n    // Get viewport\n    const viewport = page.getViewport({ scale: 1.0 });\n\n    // Extract text content\n    const textContent = await page.getTextContent();\n    const viewportWidth = viewport.width;\n    const viewportHeight = viewport.height;\n    const viewportTransform = viewport.transform;\n\n    const textItems: TextItem[] = [];\n    const garbledTextRegions: BoundingBox[] = [];\n\n    for (const item of textContent.items) {\n      // Skip items with zero dimensions\n      if (item.height === 0 || item.width === 0) continue;\n\n      // Apply viewport transformation to convert PDF coordinates to screen coordinates\n      // This properly handles Y-axis flip (PDF is bottom-up, screen is top-down)\n      const cm = multiplyMatrices(viewportTransform, item.transform);\n\n      // Get lower-left corner (text space origin)\n      const ll = applyTransformation({ x: 0, y: 0 }, cm);\n      const scaleX = Math.sqrt(item.transform[0] ** 2 + item.transform[1] ** 2);\n      const scaleY = Math.sqrt(item.transform[2] ** 2 + item.transform[3] ** 2);\n      const ur = applyTransformation({ x: item.width / scaleX, y: item.height / scaleY }, cm);\n\n      const left = Math.min(ll.x, ur.x);\n      const right = Math.max(ll.x, ur.x);\n      const top = Math.min(ll.y, ur.y);\n      const bottom = Math.max(ll.y, ur.y);\n\n      // Skip items that are off-page (negative coordinates or beyond page bounds)\n      if (top < 0 || left < 0 || top > viewportHeight || left > viewportWidth) continue;\n\n      const width = right - left;\n      const height = bottom - top;\n\n      // Get rotation angle from the transformation matrix\n      let rotation = getRotation(cm);\n      if (rotation < 0) rotation += 360;\n\n      // Decode buggy font markers using glyph names from font metadata\n      let decodedStr = item.str;\n      if (decodedStr.includes(BUGGY_FONT_MARKER_CHECK)) {\n        BUGGY_FONT_MARKER_RE.lastIndex = 0;\n        decodedStr = decodeBuggyFontMarkers(decodedStr);\n      }\n\n      // Handle pipe-separated characters: \" |a|  |r|  |X| \" -> \"arX\"\n      if (decodedStr.includes(\"|\")) {\n        PIPE_PATTERN_REGEX.lastIndex = 0;\n        const matches = [...decodedStr.matchAll(PIPE_PATTERN_REGEX)];\n        if (matches.length > 0) {\n          decodedStr = matches.map((m) => m[1]).join(\"\");\n        }\n      }\n\n      // Skip garbled text from fonts with corrupted ToUnicode mappings\n      if (isGarbledFontOutput(decodedStr)) {\n        garbledTextRegions.push({ x: left, y: top, width, height });\n        continue;\n      }\n\n      // Strip remaining control characters, map Windows-1252, decompose ligatures\n      decodedStr = stripControlChars(decodedStr);\n\n      textItems.push({\n        str: decodedStr,\n        x: left,\n        y: top,\n        width,\n        height,\n        w: width,\n        h: height,\n        r: rotation,\n        fontName: item.fontName,\n        fontSize: Math.sqrt(\n          item.transform[0] * item.transform[0] + item.transform[1] * item.transform[1]\n        ),\n        confidence: 1.0,\n      });\n    }\n\n    let images: Image[] = [];\n    if (options?.extractImages !== false) {\n      try {\n        const pdfInput = this.currentPdfPath || this.currentPdfData || doc.data;\n        if (!this.pdfiumRenderer) {\n          this.pdfiumRenderer = new PdfiumRenderer();\n          await this.pdfiumRenderer.loadDocument(pdfInput);\n        }\n        const imageBounds = await this.pdfiumRenderer.extractImageBounds(pdfInput, pageNum);\n        images = imageBounds.map((bounds) => ({\n          x: bounds.x,\n          y: bounds.y,\n          width: bounds.width,\n          height: bounds.height,\n        }));\n      } catch {\n        // Image extraction is best-effort\n      }\n    }\n\n    // Skip annotation extraction - not currently used in processing pipeline\n    // Can be re-enabled if needed for link extraction, etc.\n    const annotations: Annotation[] = [];\n\n    await page.cleanup();\n\n    return {\n      pageNum,\n      width: viewport.width,\n      height: viewport.height,\n      textItems,\n      images,\n      annotations,\n      garbledTextRegions: garbledTextRegions.length > 0 ? garbledTextRegions : undefined,\n    };\n  }\n\n  async extractAllPages(\n    doc: PdfDocument,\n    maxPages?: number,\n    targetPages?: string,\n    options?: ExtractOptions\n  ): Promise<PageData[]> {\n    const numPages = Math.min(doc.numPages, maxPages || doc.numPages);\n\n    const pages: PageData[] = [];\n\n    // Parse target pages if specified\n    let pageNumbers: number[];\n    if (targetPages) {\n      pageNumbers = this.parseTargetPages(targetPages, doc.numPages);\n    } else {\n      pageNumbers = Array.from({ length: numPages }, (_, i) => i + 1);\n    }\n\n    for (const pageNum of pageNumbers) {\n      if (maxPages && pages.length >= maxPages) {\n        break;\n      }\n      const pageData = await this.extractPage(doc, pageNum, options);\n      pages.push(pageData);\n    }\n\n    return pages;\n  }\n\n  async renderPageImage(\n    _doc: PdfDocument,\n    pageNum: number,\n    dpi: number,\n    password?: string\n  ): Promise<Buffer> {\n    const pdfInput = this.currentPdfPath || this.currentPdfData;\n    if (!pdfInput) {\n      throw new Error(\"No PDF path or data available for rendering\");\n    }\n\n    if (!this.pdfiumRenderer) {\n      this.pdfiumRenderer = new PdfiumRenderer();\n      await this.pdfiumRenderer.loadDocument(pdfInput, password);\n    }\n\n    return await this.pdfiumRenderer.renderPageToBuffer(pdfInput, pageNum, dpi, password);\n  }\n\n  async close(doc: PdfDocument): Promise<void> {\n    const pdfDocument = (doc as PdfJsExtendedDocument)._pdfDocument;\n    if (pdfDocument && pdfDocument.destroy) {\n      await pdfDocument.destroy();\n    }\n\n    // Clean up PDFium renderer (only if it was initialized)\n    if (this.pdfiumRenderer) {\n      await this.pdfiumRenderer.close();\n      this.pdfiumRenderer = null;\n    }\n    this.currentPdfPath = null;\n    this.currentPdfData = null;\n  }\n\n  private parseTargetPages(targetPages: string, maxPages: number): number[] {\n    const pages: number[] = [];\n    const parts = targetPages.split(\",\");\n\n    for (const part of parts) {\n      const trimmed = part.trim();\n      if (trimmed.includes(\"-\")) {\n        // Range: \"1-5\"\n        const [start, end] = trimmed.split(\"-\").map((n) => parseInt(n.trim()));\n        for (let i = start; i <= Math.min(end, maxPages); i++) {\n          if (i >= 1) {\n            pages.push(i);\n          }\n        }\n      } else {\n        // Single page: \"10\"\n        const pageNum = parseInt(trimmed);\n        if (pageNum >= 1 && pageNum <= maxPages) {\n          pages.push(pageNum);\n        }\n      }\n    }\n\n    return [...new Set(pages)].sort((a, b) => a - b);\n  }\n}\n"
  },
  {
    "path": "src/engines/pdf/pdfjsImporter.ts",
    "content": "import { fileURLToPath } from \"node:url\";\nimport { dirname } from \"node:path\";\n\nexport async function importPdfJs() {\n  const pdfUrl = new URL(\"../../vendor/pdfjs/pdf.mjs\", import.meta.url);\n  const pdfjs = await import(pdfUrl.href);\n\n  const dirPath = dirname(fileURLToPath(pdfUrl));\n  return {\n    fn: pdfjs.getDocument,\n    dir: dirPath,\n  };\n}\n"
  },
  {
    "path": "src/index.ts",
    "content": "#!/usr/bin/env node\n\nimport { program } from \"../cli/parse.js\";\n\n// Run the CLI\nprogram.parse(process.argv);\n"
  },
  {
    "path": "src/lib.ts",
    "content": "/**\n * @packageDocumentation\n *\n * LiteParse — open-source PDF parsing with spatial text extraction, OCR, and bounding boxes.\n *\n * @example\n * ```typescript\n * import { LiteParse } from \"@llamaindex/liteparse\";\n *\n * const parser = new LiteParse({ ocrEnabled: true });\n * const result = await parser.parse(\"document.pdf\");\n * console.log(result.text);\n * ```\n */\nexport { LiteParse } from \"./core/parser.js\";\nexport { searchItems } from \"./processing/searchItems.js\";\nexport type {\n  LiteParseConfig,\n  LiteParseInput,\n  OutputFormat,\n  ParseResult,\n  ParseResultJson,\n  ParsedPage,\n  BoundingBox,\n  TextItem,\n  JsonTextItem,\n  SearchItemsOptions,\n  ScreenshotResult,\n  MarkupData,\n} from \"./core/types.js\";\nexport type { GridDebugConfig } from \"./processing/gridDebugLogger.js\";\n"
  },
  {
    "path": "src/output/README.md",
    "content": "# src/output/\n\nOutput formatters that convert parsed document data into different formats.\n\n## Files\n\n### json.ts\n**Structured JSON output formatter.**\n\n**Functions:**\n\n`buildJSON(pages)` - Builds structured JSON object:\n```javascript\n{\n  pages: [{\n    page: number,\n    width: number,\n    height: number,\n    text: string,\n    textItems: [{\n      text: string,\n      x, y, width, height: number,\n      fontName: string,\n      fontSize: number,\n      confidence: number       // 1.0 for native PDF text, 0.0-1.0 for OCR\n    }],\n    boundingBoxes: BoundingBox[],\n  }]\n}\n```\n\n`formatJSON(result)` - Returns JSON string with 2-space indentation.\n\n**Use Case:**\n- When you need structured data for further processing\n- Integration with other tools or pipelines\n- Debugging text extraction issues\n\n---\n\n### text.ts\n**Plain text output formatter.**\n\n**Functions:**\n\n`formatText(result)` - Formats all pages with headers:\n```\n--- Page 1 ---\n[page 1 text]\n\n--- Page 2 ---\n[page 2 text]\n```\n\n`formatPageText(page)` - Returns single page text (no header).\n\n**Use Case:**\n- Human-readable output\n- Piping to other tools (grep, awk, etc.)\n- Quick document inspection\n\n---\n\n## Adding a New Output Format\n\n1. Create new file in this directory (e.g., `markdown.ts`)\n2. Export formatter function(s)\n3. Add format to `OutputFormat` type in `src/core/types.ts`\n4. Add case to switch in `src/core/parser.ts` `parse()` method\n5. Add CLI option in `cli/parse.ts`\n\n**Example: Adding Markdown format**\n```typescript\n// src/output/markdown.ts\nexport function formatMarkdown(result: ParseResult): string {\n  return result.pages.map(page => {\n    return `## Page ${page.pageNum}\\n\\n${page.text}`;\n  }).join('\\n\\n---\\n\\n');\n}\n```\n"
  },
  {
    "path": "src/output/json.test.ts",
    "content": "import { describe, it, expect } from \"vitest\";\nimport { buildJSON, formatJSON } from \"./json\";\n\nconst results = [\n  { text: \"Hello World\", bbox: [10, 20, 200, 40], confidence: 0.98 },\n  { text: \"Sample text\", bbox: [10, 50, 180, 70], confidence: 0.85 },\n  { text: \"Page footer\", bbox: [10, 750, 300, 770], confidence: 0.76 },\n];\n\nconst textItems = results\n  .filter((r) => r.confidence > 0.1) // Filter low confidence\n  .filter((r) => {\n    // Filter out OCR text that already exists in native PDF text\n    const ocrText = r.text.trim().toLowerCase();\n    return ocrText.length > 0;\n  })\n  .map((r) => ({\n    str: r.text,\n    x: r.bbox[0],\n    y: r.bbox[1],\n    width: r.bbox[2] - r.bbox[0],\n    height: r.bbox[3] - r.bbox[1],\n    w: r.bbox[2] - r.bbox[0],\n    h: r.bbox[3] - r.bbox[1],\n    fontName: \"OCR\",\n    fontSize: r.bbox[3] - r.bbox[1],\n  }));\n\nconst textItemsJSON = results.map((r) => ({\n  text: r.text,\n  x: r.bbox[0],\n  y: r.bbox[1],\n  width: r.bbox[2] - r.bbox[0],\n  height: r.bbox[3] - r.bbox[1],\n  fontName: \"OCR\",\n  fontSize: r.bbox[3] - r.bbox[1],\n  confidence: 1.0,\n}));\n\nconst pages = [\n  {\n    pageNum: 1,\n    width: 612,\n    height: 792,\n    text: \"Sample text for page 1\",\n    textItems: textItems,\n    boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n  },\n  {\n    pageNum: 2,\n    width: 612,\n    height: 792,\n    text: \"Sample text for page 2\",\n    textItems: textItems,\n    boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n  },\n  {\n    pageNum: 3,\n    width: 612,\n    height: 792,\n    text: \"Sample text for page 3\",\n    textItems: textItems,\n    boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n  },\n  {\n    pageNum: 4,\n    width: 612,\n    height: 792,\n    text: \"Sample text for page 4\",\n    textItems: textItems,\n    boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n  },\n  {\n    pageNum: 5,\n    width: 612,\n    height: 792,\n    text: \"Sample text for page 5\",\n    textItems: textItems,\n    boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n  },\n];\n\n// Native PDF text item (confidence defaults to 1.0)\nconst nativeTextItem = {\n  str: \"Native text\",\n  x: 10,\n  y: 20,\n  width: 100,\n  height: 15,\n  w: 100,\n  h: 15,\n  fontName: \"Helvetica\",\n  fontSize: 12,\n  confidence: 1.0,\n};\n\n// OCR text item (confidence from OCR engine)\nconst ocrTextItem = {\n  str: \"OCR detected text\",\n  x: 10,\n  y: 50,\n  width: 150,\n  height: 20,\n  w: 150,\n  h: 20,\n  fontName: \"OCR\",\n  fontSize: 20,\n  confidence: 0.95,\n};\n\nconst mixedPage = {\n  pageNum: 1,\n  width: 612,\n  height: 792,\n  text: \"Native text\\nOCR detected text\",\n  textItems: [nativeTextItem, ocrTextItem],\n  boundingBoxes: [],\n};\n\nconst pagesJSON = {\n  pages: [\n    {\n      page: 1,\n      width: 612,\n      height: 792,\n      text: \"Sample text for page 1\",\n      textItems: textItemsJSON,\n      boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n    },\n    {\n      page: 2,\n      width: 612,\n      height: 792,\n      text: \"Sample text for page 2\",\n      textItems: textItemsJSON,\n      boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n    },\n    {\n      page: 3,\n      width: 612,\n      height: 792,\n      text: \"Sample text for page 3\",\n      textItems: textItemsJSON,\n      boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n    },\n    {\n      page: 4,\n      width: 612,\n      height: 792,\n      text: \"Sample text for page 4\",\n      textItems: textItemsJSON,\n      boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n    },\n    {\n      page: 5,\n      width: 612,\n      height: 792,\n      text: \"Sample text for page 5\",\n      textItems: textItemsJSON,\n      boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n    },\n  ],\n};\n\nconst parseResult = {\n  pages: pages,\n  text: \"hello world\",\n  json: undefined,\n};\n\ndescribe(\"test json utilities\", () => {\n  it(\"test buildJSON\", () => {\n    const result = buildJSON(pages);\n    expect(result).toStrictEqual(pagesJSON);\n  });\n\n  it(\"test formatJSON\", () => {\n    const result = formatJSON(parseResult);\n    expect(result).toBe(JSON.stringify(pagesJSON, null, 2));\n  });\n});\n\ndescribe(\"confidence field\", () => {\n  it(\"includes OCR confidence score for OCR items\", () => {\n    const result = buildJSON([mixedPage]);\n    const items = result.pages[0].textItems;\n    const ocrItem = items.find((i) => i.text === \"OCR detected text\");\n    expect(ocrItem?.confidence).toBe(0.95);\n  });\n\n  it(\"defaults to 1.0 for native PDF items\", () => {\n    const result = buildJSON([mixedPage]);\n    const items = result.pages[0].textItems;\n    const nativeItem = items.find((i) => i.text === \"Native text\");\n    expect(nativeItem?.confidence).toBe(1.0);\n  });\n\n  it(\"preserves confidence of 0.0\", () => {\n    const zeroConfidenceItem = { ...ocrTextItem, confidence: 0.0 };\n    const page = { ...mixedPage, textItems: [zeroConfidenceItem] };\n    const result = buildJSON([page]);\n    const item = result.pages[0].textItems[0];\n    expect(item.confidence).toBe(0.0);\n  });\n\n  it(\"defaults to 1.0 when confidence is undefined\", () => {\n    const { confidence: _confidence, ...itemWithoutConfidence } = nativeTextItem;\n    const page = { ...mixedPage, textItems: [itemWithoutConfidence] };\n    const result = buildJSON([page]);\n    const item = result.pages[0].textItems[0];\n    expect(item.confidence).toBe(1.0);\n  });\n});\n"
  },
  {
    "path": "src/output/json.ts",
    "content": "import { ParseResult, ParsedPage, ParseResultJson } from \"../core/types.js\";\n\n/**\n * Build JSON output from parsed pages\n */\nexport function buildJSON(pages: ParsedPage[]): ParseResultJson {\n  return {\n    pages: pages.map((page) => ({\n      page: page.pageNum,\n      width: page.width,\n      height: page.height,\n      text: page.text,\n      textItems: page.textItems.map((item) => ({\n        text: item.str,\n        x: item.x,\n        y: item.y,\n        width: item.width,\n        height: item.height,\n        fontName: item.fontName,\n        fontSize: item.fontSize,\n        confidence: item.confidence ?? 1.0,\n      })),\n      boundingBoxes: page.boundingBoxes || [],\n    })),\n  };\n}\n\n/**\n * Format result as JSON string\n */\nexport function formatJSON(result: ParseResult): string {\n  const jsonData = buildJSON(result.pages);\n  return JSON.stringify(jsonData, null, 2);\n}\n"
  },
  {
    "path": "src/output/text.test.ts",
    "content": "import { describe, expect, it } from \"vitest\";\nimport { formatPageText, formatText } from \"./text\";\n\nconst pages = [\n  {\n    pageNum: 1,\n    width: 612,\n    height: 792,\n    text: \"Sample text for page 1\",\n    textItems: [],\n    boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n  },\n  {\n    pageNum: 2,\n    width: 612,\n    height: 792,\n    text: \"Sample text for page 2\",\n    textItems: [],\n    boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n  },\n  {\n    pageNum: 3,\n    width: 612,\n    height: 792,\n    text: \"Sample text for page 3\",\n    textItems: [],\n    boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n  },\n  {\n    pageNum: 4,\n    width: 612,\n    height: 792,\n    text: \"Sample text for page 4\",\n    textItems: [],\n    boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n  },\n  {\n    pageNum: 5,\n    width: 612,\n    height: 792,\n    text: \"Sample text for page 5\",\n    textItems: [],\n    boundingBoxes: [{ x1: 0, y1: 0, x2: 300, y2: 400 }],\n  },\n];\n\nconst parseResult = {\n  pages: pages,\n  text: \"hello world\",\n  json: undefined,\n};\n\ndescribe(\"test text utilites\", () => {\n  it(\"test formatText\", () => {\n    const result = formatText(parseResult);\n    expect(result).toBe(\n      pages\n        .map((page) => {\n          const header = `\\n--- Page ${page.pageNum} ---\\n`;\n          return header + page.text;\n        })\n        .join(\"\\n\\n\")\n    );\n  });\n\n  it(\"test formatPageText\", () => {\n    const result = formatPageText(pages[0]);\n    expect(result).toBe(pages[0].text);\n  });\n});\n"
  },
  {
    "path": "src/output/text.ts",
    "content": "import { ParseResult, ParsedPage } from \"../core/types.js\";\n\n/**\n * Format pages as plain text\n */\nexport function formatText(result: ParseResult): string {\n  const pageTexts = result.pages.map((page) => {\n    const header = `\\n--- Page ${page.pageNum} ---\\n`;\n    return header + page.text;\n  });\n\n  return pageTexts.join(\"\\n\\n\");\n}\n\n/**\n * Format single page as text\n */\nexport function formatPageText(page: ParsedPage): string {\n  return page.text;\n}\n"
  },
  {
    "path": "src/processing/README.md",
    "content": "# src/processing/\n\nThe processing module is the **heart of LiteParse** - responsible for transforming raw PDF content into structured, spatially-aware text. This is where text extraction, layout reconstruction, and OCR integration happen.\n\n## Files\n\n### grid.ts\n**Thin wrapper around gridProjection.ts.**\n\nSimply merges user config with defaults and calls `projectPagesToGridComplete`. Exists to provide a cleaner import path and handle configuration.\n\n---\n\n### gridProjection.ts (~1650 lines)\n**The most complex module - spatial text layout reconstruction.**\n\nThis is the core algorithm that converts raw PDF text items into readable, properly-ordered text that preserves document layout.\n\n**Key Concepts:**\n\n1. **Anchors**: Track where text aligns on the page\n   - `anchorLeft` - Text left-edges (column starts)\n   - `anchorRight` - Text right-edges (column ends)\n   - `anchorCenter` - Text centers (centered content)\n\n2. **Snap Types**: How text aligns to columns\n   - `left` - Text snaps to left edge of a column\n   - `right` - Text snaps to right edge\n   - `center` - Text is centered\n   - `floating` - Unaligned/justified text\n\n3. **Forward Anchors**: Carry alignment information between lines\n   - Enables consistent column detection across the page\n   - Prevents duplicate text detection (`isDup` flag)\n\n4. **Rotation Handling**: PDFs can contain rotated text (90°, 180°, 270°)\n   - `handleRotationReadingOrder()` transforms rotated text to reading order\n   - Groups text by rotation value, not just position\n   - For 90°/270° text without visual overlap: transforms coordinates to maintain reading order\n   - For 90°/270° text with overlap: keeps in place but marks as rotated\n   - For 180° text: flips coordinates to correct upside-down text\n\n5. **Margin Line Number Detection**: Two-column documents often have line numbers in the gutter\n   - Detects short numeric items (1-2 digits) near the page midpoint\n   - Marks them as `isMarginLineNumber` to prevent merging with column content\n   - Ensures line numbers appear on their own line\n\n**Algorithm Flow:**\n1. Build bounding boxes from text items and OCR data\n2. Handle rotated text reading order (`handleRotationReadingOrder`)\n3. Sort text into lines by Y-coordinate (`bboxToLine`)\n4. Extract anchor points from all text items (`extractAnchorsPointsFromLines`)\n5. Try to align floating text with nearby anchors (`tryAlignFloating`)\n6. Detect text snapping (left, right, center, or floating)\n7. Project lines onto character grid with proper spacing\n8. Apply markup tags (highlight, underline, strikeout)\n9. Clean up sparse blocks and margins\n\n**Key Functions:**\n- `handleRotationReadingOrder()` - Transform rotated text to correct reading order\n- `bboxToLine()` - Group text items into lines with Y-tolerance for subscripts\n- `extractAnchorsPointsFromLines()` - Identify alignment anchors and deduplicate\n- `tryAlignFloating()` - Align floating bboxes with anchors on adjacent lines\n- `projectToGrid()` - Main projection algorithm (accepts a `GridDebugLogger` for tracing)\n- `projectPagesToGrid()` - Process all pages with shared anchors, creates debug logger from config\n\n**Constants:**\n- `FLOATING_SPACES = 2` - Minimum spaces between floating text\n- `COLUMN_SPACES = 4` - Minimum spaces between columns\n- `SMALL_FONT_SIZE_THRESHOLD = 2` - Filter very small text (2pt @ 72 DPI)\n- `Y_SORT_TOLERANCE` - Tolerance for same-line detection (scales with median height, min 5.0)\n\n**Design Decisions:**\n- **Anchor rounding**: Groups anchor x-coords by nearest 1/4 unit to handle slight variations\n- **Sparse block compression**: Reduces excessive whitespace in sparse layouts (>80% whitespace)\n- **Small text filtering**: Lines with >50% small text can be filtered (configurable)\n- **Rotation grouping**: Text is grouped by rotation value before processing, so rotated blocks stay together even when X coordinates overlap with non-rotated content\n- **Y-tolerance sorting**: Items within `Y_SORT_TOLERANCE` are considered same line, handling floating-point precision and subscripts/superscripts\n\n---\n\n### gridDebugLogger.ts\n**Targeted debug logging for grid projection.**\n\nProvides a `GridDebugLogger` class that traces projection decisions at every stage — block detection, anchor extraction, snap assignment, rendering, flowing text classification, and forward anchor updates. Uses a filter system to narrow output to specific elements.\n\n**`GridDebugConfig` options:**\n- `enabled` - Master switch\n- `textFilter` - Only log elements whose text contains these substrings (case-insensitive)\n- `lineFilter` - Only log elements on these line indices (0-based)\n- `pageFilter` - Only log elements on this page number (1-indexed)\n- `regionFilter` - Only log elements within a bounding region `{ x1, y1, x2, y2 }`\n- `outputPath` - Write log to a file instead of stderr\n- `visualize` - Generate PNG visualizations (see gridVisualizer.ts)\n- `visualizePath` - Directory for visualization PNGs (default: `./debug-output`)\n\n**Log phases:** `page`, `blocks`, `anchors`, `snap`, `render`, `flowing`, `forward-anchor`, `dedup`, `lines`\n\nWhen disabled, a zero-cost `NoopGridDebugLogger` singleton is used — no runtime overhead in production.\n\n---\n\n### gridVisualizer.ts\n**PNG visualization of projected text output.**\n\nRenders the projected text as a monospace character grid image using sharp with an SVG overlay. Each character is drawn at its grid position, color-coded by snap type:\n- **Blue** — left snap\n- **Red** — right snap\n- **Green** — center snap\n- **Gray** — floating (unsnapped)\n- **Yellow** — flowing text\n\nText segments get colored background rectangles and colored text, making it easy to compare the projection output directly against the original PDF page screenshot. Includes a color legend.\n\nCalled automatically when `debug.visualize` is enabled. Output files are named `page-{N}-grid.png` in the configured directory.\n\n---\n\n### bbox.ts\n**Bounding box construction and OCR integration.**\n\n**Key Functions:**\n\n`buildBbox(pageData, config)` - Main function that:\n1. Converts `TextItem[]` to `ProjectionTextBox[]` with additional metadata\n2. Processes embedded images for OCR if enabled\n3. Filters images by size, position, and type\n4. Filters OCR results that overlap with existing text (50% spatial threshold)\n5. Filters OCR results whose text content already exists in native PDF text (content-based deduplication)\n6. Returns combined text boxes for grid projection\n\n`buildBoundingBoxes(textItems)` - Simple conversion of text items to `BoundingBox[]` format (x1, y1, x2, y2).\n\n**OCR Filtering Constants:**\n- `OCR_CONFIDENCE_THRESHOLD = 0.1` - Minimum OCR confidence\n- `OCR_OVERLAP_THRESHOLD = 0.5` - Reject OCR if >50% overlaps existing text\n- `MAX_IMAGES_PER_PAGE = 10` - Limit images processed per page\n- `MIN_IMAGE_DIMENSION = 12` - Skip tiny images\n- `MIN_IMAGE_AREA = 200` - Skip small-area images\n\n**Design Decisions:**\n- **Spatial overlap filtering**: Prevents duplicate text when OCR and PDF extraction detect the same content at the same location. Native PDF text is preferred over OCR.\n- **Content-based deduplication**: Filters OCR text that matches existing PDF text content regardless of position. This handles cases like watermarks or embedded images containing text that already appears elsewhere on the page.\n\n---\n\n### ocrUtils.ts\n**OCR result parsing and coordinate conversion.**\n\n**Key Functions:**\n\n`parseImageOcrBlocks(image)`:\n- Converts OCR bounding boxes from image space to page space\n- Handles scale factors and coordinate ratios\n- Returns `OcrBlock[]` with both page-space and raw coordinates\n\n`easyOcrResultLinesToList(stdOutResult)`:\n- Parses EasyOCR stdout format into structured data\n- Format: `([[x1,y1], [x2,y2], [x3,y3], [x4,y4]], 'text', confidence)`\n\n**Coordinate Systems:**\n- **Image space**: Coordinates relative to the OCR'd image\n- **Page space**: Coordinates relative to the PDF page viewport\n- Conversion uses `xRatio = image.width / coords.w`\n\n---\n\n### textUtils.ts\n**Unicode subscript and superscript conversion.**\n\nUsed for scientific notation and mathematical text.\n\n- `strToSubscriptString(str)` - Converts \"H2O\" → \"H₂O\"\n- `strToPostScript(str)` - Converts \"x2\" → \"x²\"\n\nSupports: digits 0-9, +/-, common letters (a-z, A-Z subset)\n\nIf any character lacks a Unicode equivalent, returns original string unchanged.\n\n---\n\n### cleanText.ts\n**Post-processing text cleanup.**\n\n`cleanRawText(pages, config)`:\n1. **Margin removal** (per page):\n   - Detects consistent left margin (leading whitespace)\n   - Removes top margin (empty lines at start)\n   - Removes bottom margin (empty lines at end)\n   - Trims right margin (trailing whitespace)\n2. **Null character removal**: Replaces `\\u0000` with spaces\n\n---\n\n### markupUtils.ts\n**Apply inline markup tags from PDF annotations.**\n\n`applyMarkupTags(markup, text)` - Wraps text with markup:\n- Strikeout → `~~text~~`\n- Underline → `__text__`\n- Squiggly → `__text__` (same as underline)\n- Highlight → `==text==`\n\nThese tags can be converted to markdown or other formats downstream.\n\n---\n\n## Data Flow\n\n```\nPageData (from PDF engine)\n    │\n    ▼\nbuildBbox() ─────────────────────────────┐\n    │                                    │\n    │  Converts TextItems to             │  Processes embedded\n    │  ProjectionTextBox[]               │  images with OCR data\n    │                                    │\n    └────────────┬───────────────────────┘\n                 │\n                 ▼\n    ProjectionTextBox[] (unified text boxes)\n                 │\n                 ▼\n    projectPagesToGrid()\n                 │\n    ┌────────────┼────────────┐\n    │            │            │\n    ▼            ▼            ▼\nExtract      Detect        Project\nAnchors      Snapping      to Grid\n    │            │            │\n    └────────────┴────────────┘\n                 │\n                 ▼\n    ParsedPage[] with reconstructed text\n                 │\n                 ▼\n    cleanRawText() - Remove margins, cleanup\n                 │\n                 ▼\n    Final text output\n```\n\n## Common Modifications\n\n### Adjusting column detection sensitivity\nModify `roundAnchor()` in `gridProjection.ts` - currently rounds to nearest 1/4 unit.\n\n### Changing OCR overlap threshold\nModify `OCR_OVERLAP_THRESHOLD` in `bbox.ts` (default: 0.5 = 50%).\n\n### Adding new markup types\n1. Add field to `MarkupData` in `src/core/types.ts`\n2. Add case in `applyMarkupTags()` in `markupUtils.ts`\n"
  },
  {
    "path": "src/processing/bbox.test.ts",
    "content": "import { expect, describe, it } from \"vitest\";\nimport { buildBbox, buildBoundingBoxes, filterImagesForOCR } from \"./bbox\";\nimport { LiteParseConfig } from \"../lib\";\nimport { DEFAULT_CONFIG } from \"../core/config\";\nimport { EasyOcrResultLine } from \"../engines/pdf/interface\";\n\ndescribe(\"test filterImagesForOCR\", () => {\n  it(\"test valid image\", () => {\n    const images = [\n      {\n        type: \"photo\",\n        width: 200,\n        height: 200,\n        x: 10,\n        y: 10,\n        coords: { x: 10, y: 10, w: 200, h: 200 },\n      },\n    ];\n    const page = { width: 1000, height: 1000 };\n    const result = filterImagesForOCR(images, page);\n    expect(result).toStrictEqual(images);\n  });\n\n  it(\"test filter on patterns\", () => {\n    const images = [\n      { type: \"g_background\", width: 200, height: 200, x: 0, y: 0 },\n      { type: \"pattern_stripe\", width: 200, height: 200, x: 0, y: 0 },\n      {\n        type: \"photo\",\n        width: 200,\n        height: 200,\n        x: 0,\n        y: 0,\n        coords: { x: 0, y: 0, w: 200, h: 200 },\n      },\n    ];\n    const page = { width: 1000, height: 1000 };\n    const result = filterImagesForOCR(images, page);\n    expect(result).toStrictEqual([images[2]]);\n  });\n\n  it(\"test filter layout\", () => {\n    const images = [\n      {\n        type: \"layout_header\",\n        width: 300,\n        height: 300,\n        x: 0,\n        y: 0,\n        coords: { x: 0, y: 0, w: 300, h: 300 },\n      },\n    ];\n    const page = { width: 1000, height: 1000 };\n    const result = filterImagesForOCR(images, page);\n    expect(result.length).toBe(0);\n  });\n\n  it(\"test out of viewport\", () => {\n    const images = [\n      {\n        type: \"photo\",\n        width: 200,\n        height: 200,\n        coords: { x: 1100, y: 0, w: 200, h: 200 },\n        x: 0,\n        y: 0,\n      },\n    ];\n    const page = { width: 1000, height: 1000 };\n    const result = filterImagesForOCR(images, page);\n    expect(result.length).toBe(0);\n  });\n\n  it(\"test min dimensions\", () => {\n    const images = [\n      { type: \"photo\", width: 5, height: 5, x: 0, y: 0, coords: { x: 0, y: 0, w: 5, h: 5 } },\n    ];\n    const page = { width: 1000, height: 1000 };\n    const result = filterImagesForOCR(images, page);\n    expect(result.length).toBe(0);\n  });\n\n  it(\"test max images per page\", () => {\n    const images = [\n      {\n        type: \"photo\",\n        width: 100,\n        height: 100,\n        x: 0,\n        y: 0,\n        coords: { x: 0, y: 0, w: 100, h: 100 },\n      },\n      {\n        type: \"photo\",\n        width: 100,\n        height: 100,\n        x: 0,\n        y: 0,\n        coords: { x: 0, y: 0, w: 500, h: 500 },\n      },\n      {\n        type: \"photo\",\n        width: 100,\n        height: 100,\n        x: 0,\n        y: 0,\n        coords: { x: 0, y: 0, w: 300, h: 300 },\n      },\n      {\n        type: \"photo\",\n        width: 100,\n        height: 100,\n        x: 0,\n        y: 0,\n        coords: { x: 0, y: 0, w: 100, h: 100 },\n      },\n      {\n        type: \"photo\",\n        width: 100,\n        height: 100,\n        x: 0,\n        y: 0,\n        coords: { x: 0, y: 0, w: 500, h: 500 },\n      },\n      {\n        type: \"photo\",\n        width: 100,\n        height: 100,\n        x: 0,\n        y: 0,\n        coords: { x: 0, y: 0, w: 300, h: 300 },\n      },\n      {\n        type: \"photo\",\n        width: 100,\n        height: 100,\n        x: 0,\n        y: 0,\n        coords: { x: 0, y: 0, w: 100, h: 100 },\n      },\n      {\n        type: \"photo\",\n        width: 100,\n        height: 100,\n        x: 0,\n        y: 0,\n        coords: { x: 0, y: 0, w: 500, h: 500 },\n      },\n      {\n        type: \"photo\",\n        width: 100,\n        height: 100,\n        x: 0,\n        y: 0,\n        coords: { x: 0, y: 0, w: 300, h: 300 },\n      },\n      {\n        type: \"photo\",\n        width: 100,\n        height: 100,\n        x: 0,\n        y: 0,\n        coords: { x: 0, y: 0, w: 100, h: 100 },\n      },\n      {\n        type: \"photo\",\n        width: 100,\n        height: 100,\n        x: 0,\n        y: 0,\n        coords: { x: 0, y: 0, w: 500, h: 500 },\n      },\n      {\n        type: \"photo\",\n        width: 100,\n        height: 100,\n        x: 0,\n        y: 0,\n        coords: { x: 0, y: 0, w: 300, h: 300 },\n      },\n    ];\n    const page = { width: 1000, height: 1000 };\n    const result = filterImagesForOCR(images, page);\n    expect(result).toStrictEqual(images.slice(0, 10));\n  });\n});\n\ndescribe(\"test buildBox\", () => {\n  it(\"test with OCR disabled\", () => {\n    const pageData = {\n      pageNum: 1,\n      width: 612,\n      height: 792,\n      textItems: [\n        { str: \"Hello World\", x: 50, y: 100, width: 120, height: 14, w: 120, h: 14 },\n        { str: \"Some body text\", x: 50, y: 130, width: 200, height: 14, w: 200, h: 14 },\n      ],\n      images: [],\n    };\n    const config: LiteParseConfig = { ...DEFAULT_CONFIG, ocrEnabled: false };\n\n    const expectedOutput = [\n      {\n        x: 50,\n        y: 100,\n        rx: 0,\n        ry: 0,\n        w: 120,\n        h: 14,\n        r: 0,\n        str: \"Hello World\",\n        strLength: 11,\n        pageBbox: { x: 50, y: 100, w: 120, h: 14 },\n        vgap: undefined,\n        isPlaceholder: undefined,\n      },\n      {\n        x: 50,\n        y: 130,\n        rx: 0,\n        ry: 0,\n        w: 200,\n        h: 14,\n        r: 0,\n        str: \"Some body text\",\n        strLength: 14,\n        pageBbox: { x: 50, y: 130, w: 200, h: 14 },\n        vgap: undefined,\n        isPlaceholder: undefined,\n      },\n    ];\n\n    const result = buildBbox(pageData, config);\n    expect(result).toStrictEqual(expectedOutput);\n  });\n\n  it(\"test with OCR enabled\", () => {\n    const pageData = {\n      pageNum: 1,\n      width: 612,\n      height: 792,\n      textItems: [\n        // Native PDF text (top-left)\n        { str: \"Hello World\", x: 50, y: 100, width: 120, height: 14, w: 120, h: 14 },\n      ],\n      images: [\n        {\n          x: 0,\n          y: 200,\n          width: 612,\n          height: 400,\n          originalOrientationAngle: 0,\n          // parseImageOcrBlocks() reads this internally:\n          ocrRaw: [\n            // Block A: no spatial overlap with native text, unique content → KEPT\n            [\n              [\n                [50, 50],\n                [250, 50],\n                [250, 70],\n                [50, 70],\n              ],\n              \"Scanned paragraph text\",\n              0.95,\n              // resolved by parseImageOcrBlocks to absolute page coords:\n              // x:50, y:50, w:200, h:20, rx/ry/rw/rh for rotated coords\n            ] as EasyOcrResultLine,\n            // Block B: text already exists in native items (\"hello world\") → FILTERED (content dedup)\n            [\n              [\n                [50, 0],\n                [170, 0],\n                [170, 14],\n                [50, 14],\n              ],\n              \"Hello World\",\n              0.97,\n              // x:50, y:200, w:120, h:14 — also overlaps native text box\n            ] as EasyOcrResultLine,\n            // Block C: low confidence → FILTERED (below threshold)\n            [\n              [\n                [300, 100],\n                [500, 100],\n                [500, 120],\n                [300, 120],\n              ],\n              \"Low confidence text\",\n              0.05,\n            ] as EasyOcrResultLine,\n          ],\n        },\n      ],\n    };\n    const config: LiteParseConfig = { ...DEFAULT_CONFIG, ocrEnabled: true };\n\n    const expectedOutput = [\n      // ── Native text item ──────────────────────────────────────────────\n      {\n        x: 50,\n        y: 100,\n        rx: 0,\n        ry: 0,\n        w: 120,\n        h: 14,\n        r: 0,\n        str: \"Hello World\",\n        strLength: 11,\n        pageBbox: { x: 50, y: 100, w: 120, h: 14 },\n        vgap: undefined,\n        isPlaceholder: undefined,\n      },\n\n      // ── OCR block A (passed all filters) ─────────────────────────────\n      {\n        fromOCR: true,\n        x: 50,\n        y: 50,\n        w: 200,\n        h: 20,\n        r: 0,\n        str: \"Scanned paragraph text\",\n        strLength: 22,\n        pageBbox: { x: 50, y: 50, w: 200, h: 20 },\n      },\n\n      // Block B removed: spatial overlap >50% of native text item AND content dedup match\n      // Block C removed: confidence 0.40 < OCR_CONFIDENCE_THRESHOLD (0.5)\n    ];\n\n    const result = buildBbox(pageData, config);\n    expect(result).toStrictEqual(expectedOutput);\n  });\n});\n\ndescribe(\"test buildBoundingBoxes\", () => {\n  it(\"test buildBoundingBoxes success\", () => {\n    const textItems = [\n      { str: \"Hello\", x: 50, y: 100, width: 60, height: 14, w: 60, h: 14 },\n      { str: \"   \", x: 50, y: 120, width: 30, height: 14, w: 30, h: 14 },\n      { str: \"World\", x: 50, y: 140, width: 80, height: 14, w: 80, h: 14 },\n    ];\n\n    const expectedOutput = [\n      { x1: 50, y1: 100, x2: 110, y2: 114 },\n      { x1: 50, y1: 140, x2: 130, y2: 154 },\n    ];\n\n    const result = buildBoundingBoxes(textItems);\n    expect(result).toStrictEqual(expectedOutput);\n  });\n});\n"
  },
  {
    "path": "src/processing/bbox.ts",
    "content": "import {\n  TextItem,\n  BoundingBox,\n  ProjectionTextBox,\n  OcrData,\n  LiteParseConfig,\n} from \"../core/types.js\";\nimport { PageData, Image } from \"../engines/pdf/interface.js\";\nimport { parseImageOcrBlocks, OcrBlock } from \"./ocrUtils.js\";\nimport { cleanOcrTableArtifacts } from \"./textUtils.js\";\n\nconst OCR_CONFIDENCE_THRESHOLD = 0.1;\n\n/**\n * Minimum overlap ratio (0-1) required to consider an OCR block as duplicate of existing text.\n * An OCR block is filtered out if:\n * - Total overlap with all text items covers more than this ratio of the OCR block area\n * - OR the OCR block covers more than this ratio of any single text item\n */\nconst OCR_OVERLAP_THRESHOLD = 0.5;\n\n/**\n * Maximum number of embedded images to process for OCR per page.\n * Keeps the largest images when limit is exceeded.\n */\nconst MAX_IMAGES_PER_PAGE = 10;\n\n/**\n * Minimum image dimensions for OCR processing\n */\nconst MIN_IMAGE_DIMENSION = 12;\nconst MIN_IMAGE_AREA = 200;\n\n/**\n * Minimum rendered image dimensions for OCR processing\n */\nconst MIN_RENDERED_DIMENSION = 6;\nconst MIN_RENDERED_AREA = 200;\n\n/**\n * Filters images that should not be OCR'd based on various criteria.\n * Returns the filtered array of images that should be processed.\n */\nexport function filterImagesForOCR(\n  images: Image[],\n  page: { width: number; height: number }\n): Image[] {\n  // Filter images that start with g_ or pattern_ (generated/pattern images)\n  let filtered = images.filter(\n    (image) => !image.type?.startsWith(\"g_\") && !image.type?.startsWith(\"pattern_\")\n  );\n\n  // Limit to max images per page, keeping the largest ones\n  if (filtered.length > MAX_IMAGES_PER_PAGE) {\n    filtered.sort((a, b) => b.width * b.height - a.width * a.height);\n    filtered = filtered.slice(0, MAX_IMAGES_PER_PAGE);\n  }\n\n  // Apply additional filtering criteria\n  filtered = filtered.filter((image) => {\n    // Ignore layout extracted images\n    if (image.type?.includes(\"layout_\")) {\n      return false;\n    }\n\n    // Get image coords (use image dimensions if coords not set)\n    const coords = image.coords || {\n      x: image.x,\n      y: image.y,\n      w: image.width,\n      h: image.height,\n    };\n\n    // Skip images that are out of viewport\n    if (\n      coords.x + coords.w < 0 || // left of page\n      coords.y + coords.h < 0 || // above page\n      coords.x > page.width || // right of page\n      coords.y > page.height // below page\n    ) {\n      return false;\n    }\n\n    // Skip small images (raw dimensions)\n    if (\n      image.width < MIN_IMAGE_DIMENSION ||\n      image.height < MIN_IMAGE_DIMENSION ||\n      image.width * image.height < MIN_IMAGE_AREA\n    ) {\n      return false;\n    }\n\n    // Skip images that render too small in the viewport\n    if (\n      coords.w < MIN_RENDERED_DIMENSION ||\n      coords.h < MIN_RENDERED_DIMENSION ||\n      coords.w * coords.h < MIN_RENDERED_AREA\n    ) {\n      return false;\n    }\n\n    return true;\n  });\n\n  return filtered;\n}\n\n/**\n * Checks if two bounding boxes overlap and returns the overlap area.\n */\nfunction getOverlapArea(\n  box1: { x: number; y: number; w: number; h: number },\n  box2: { x: number; y: number; w: number; h: number }\n): number {\n  const left = Math.max(box1.x, box2.x);\n  const right = Math.min(box1.x + box1.w, box2.x + box2.w);\n  const top = Math.max(box1.y, box2.y);\n  const bottom = Math.min(box1.y + box1.h, box2.y + box2.h);\n\n  if (left >= right || top >= bottom) {\n    return 0;\n  }\n\n  return (right - left) * (bottom - top);\n}\n\n/**\n * Filters out OCR blocks that significantly overlap with already-extracted text items.\n * This prevents duplicate text when both document text extraction and OCR detect the same content.\n * Prefers document-extracted text over OCR text.\n *\n * An OCR block is rejected if:\n * 1. The total overlap with all text items covers more than 50% of the OCR block area\n * 2. OR the OCR block covers more than 50% of any single text item's area\n */\nfunction filterOcrBlocksOverlappingWithText(\n  ocrBlocks: OcrBlock[],\n  textItems: Array<{ x: number; y: number; w: number; h: number }>\n): OcrBlock[] {\n  if (!textItems.length || !ocrBlocks.length) {\n    return ocrBlocks;\n  }\n\n  return ocrBlocks.filter((ocrBlock) => {\n    const ocrBox = {\n      x: ocrBlock.x,\n      y: ocrBlock.y,\n      w: ocrBlock.w,\n      h: ocrBlock.h,\n    };\n    const ocrArea = ocrBlock.w * ocrBlock.h;\n\n    if (ocrArea <= 0) {\n      return false;\n    }\n\n    let totalOverlapArea = 0;\n\n    // Check overlap with each text item\n    for (const textItem of textItems) {\n      const textBox = {\n        x: textItem.x,\n        y: textItem.y,\n        w: textItem.w,\n        h: textItem.h,\n      };\n      const textItemArea = textItem.w * textItem.h;\n\n      const overlapArea = getOverlapArea(ocrBox, textBox);\n\n      if (overlapArea > 0) {\n        // Accumulate total overlap for condition 1\n        totalOverlapArea += overlapArea;\n\n        // Condition 2: Reject if OCR block covers more than 50% of any single text item\n        if (textItemArea > 0 && overlapArea / textItemArea >= OCR_OVERLAP_THRESHOLD) {\n          return false;\n        }\n      }\n    }\n\n    // Condition 1: Reject if total overlap covers more than 50% of the OCR block\n    const totalOverlapRatio = totalOverlapArea / ocrArea;\n    if (totalOverlapRatio >= OCR_OVERLAP_THRESHOLD) {\n      return false;\n    }\n\n    return true;\n  });\n}\n\n/**\n * Build projection text boxes from page data, including OCR results\n * This is the complete implementation from buildBbox.ts\n */\nexport function buildBbox(pageData: PageData, config: LiteParseConfig): ProjectionTextBox[] {\n  const lines: ProjectionTextBox[] = [];\n\n  // Process all extracted text items\n  for (const item of pageData.textItems) {\n    const line: ProjectionTextBox = {\n      x: item.x,\n      y: item.y,\n      rx: item.rx || 0,\n      ry: item.ry || 0,\n      w: Math.round(item.w || item.width),\n      h: Math.round(item.h || item.height),\n      r: item.r || 0,\n      str: item.str,\n      strLength: [...item.str].length, // Handle multi-byte characters correctly\n      pageBbox: {\n        x: item.x,\n        y: item.y,\n        w: item.w || item.width,\n        h: item.h || item.height,\n      },\n      vgap: item.vgap,\n      isPlaceholder: item.isPlaceholder,\n    };\n\n    lines.push(line);\n  }\n\n  // Process OCR data if images are present\n  if (pageData.images.length && config.ocrEnabled) {\n    // Filter images that should be processed for OCR\n    const imagesToProcess = filterImagesForOCR(pageData.images, {\n      width: pageData.width,\n      height: pageData.height,\n    });\n\n    // Collect text item bounding boxes for overlap checking\n    const textItemBoxes = pageData.textItems.map((item) => ({\n      x: item.x,\n      y: item.y,\n      w: item.w || item.width,\n      h: item.h || item.height,\n    }));\n\n    // Collect text content for content-based deduplication (normalized lowercase)\n    const existingTextContent = new Set(\n      pageData.textItems.map((item) => item.str.trim().toLowerCase()).filter((s) => s.length > 0)\n    );\n\n    for (const image of imagesToProcess) {\n      // Parse OCR blocks from image\n      let ocrData = parseImageOcrBlocks(image);\n\n      // Filter by confidence threshold\n      ocrData = ocrData.filter(\n        (block) => parseFloat(block.confidence.toString()) >= OCR_CONFIDENCE_THRESHOLD\n      );\n\n      // Filter out OCR blocks that overlap with already-extracted text\n      ocrData = filterOcrBlocksOverlappingWithText(ocrData, textItemBoxes);\n\n      // Filter out OCR blocks whose text content already exists in native PDF text\n      // This catches duplicates that are at different positions (e.g., watermarks, repeated headers)\n      ocrData = ocrData.filter((block) => {\n        const ocrText = block.c.trim().toLowerCase();\n        return ocrText.length > 0 && !existingTextContent.has(ocrText);\n      });\n\n      const ocrParsed: OcrData[] = [];\n      for (const block of ocrData) {\n        const confidenceRounded = Math.round(parseFloat(block.confidence.toString()) * 1000) / 1000;\n\n        // Clean OCR artifacts from table border misreads\n        const cleanedText = cleanOcrTableArtifacts(block.c);\n\n        // Skip if cleaning removed all content\n        if (cleanedText.length === 0) {\n          continue;\n        }\n\n        const line: ProjectionTextBox = {\n          fromOCR: true,\n          x: block.x,\n          y: block.y,\n          w: block.w,\n          h: block.h,\n          r: image.originalOrientationAngle || 0,\n          str: cleanedText,\n          strLength: [...cleanedText].length,\n          pageBbox: {\n            x: block.x,\n            y: block.y,\n            w: block.w,\n            h: block.h,\n          },\n        };\n        lines.push(line);\n\n        ocrParsed.push({\n          x: block.rx,\n          y: block.ry,\n          w: block.rw,\n          h: block.rh,\n          confidence: confidenceRounded,\n          text: cleanedText,\n        });\n      }\n\n      if (ocrParsed.length) {\n        image.ocrParsed = ocrParsed;\n      }\n    }\n  }\n\n  return lines;\n}\n\n/**\n * Build bounding boxes from text items\n */\nexport function buildBoundingBoxes(textItems: TextItem[]): BoundingBox[] {\n  const bboxes: BoundingBox[] = [];\n\n  for (const item of textItems) {\n    if (item.str.trim() === \"\") {\n      continue;\n    }\n\n    bboxes.push({\n      x1: item.x,\n      y1: item.y,\n      x2: item.x + (item.w || item.width),\n      y2: item.y + (item.h || item.height),\n    });\n  }\n\n  return bboxes;\n}\n"
  },
  {
    "path": "src/processing/cleanText.test.ts",
    "content": "import { describe, expect, it } from \"vitest\";\nimport { ParsedPage } from \"../core/types.js\";\nimport { cleanRawText } from \"./cleanText.js\";\nimport { DEFAULT_CONFIG } from \"../core/config.js\";\n\nconst mockPages: ParsedPage[] = [\n  {\n    // Normal page with margins\n    pageNum: 1,\n    width: 612,\n    height: 792,\n    text: \"   Hello World   \\n   Foo Bar   \\n\",\n    textItems: [],\n  },\n  {\n    // Empty page\n    pageNum: 2,\n    width: 612,\n    height: 792,\n    text: \"   \\n   \\n\",\n    textItems: [],\n  },\n  {\n    // Single line\n    pageNum: 3,\n    width: 612,\n    height: 792,\n    text: \"  Hello  \",\n    textItems: [],\n  },\n];\n\nconst expectedTexts: string[] = [\n  // minX=3, minY=0, maxY=1 → slice(3) + trimEnd\n  \"Hello World\\nFoo Bar\",\n  // entirely empty → \"\"\n  \"\",\n  // minX=2, minY=0, maxY=0 → slice(2) + trimEnd\n  \"Hello\",\n];\n\ndescribe(\"test cleanText\", () => {\n  it(\"test cleanRawText\", () => {\n    cleanRawText(mockPages, DEFAULT_CONFIG);\n    for (let i = 0; i < mockPages.length; i++) {\n      expect(mockPages[i].text).toBe(expectedTexts[i]);\n    }\n  });\n});\n"
  },
  {
    "path": "src/processing/cleanText.ts",
    "content": "import { ParsedPage, LiteParseConfig } from \"../core/types.js\";\n\n/**\n * Detect and remove margins from a single page.\n * Removes:\n * - Left margin (consistent leading whitespace)\n * - Top margin (empty lines at start)\n * - Bottom margin (empty lines at end)\n * - Right margin (trailing whitespace on each line)\n */\nfunction detectAndRemoveMarginOnPage(page: ParsedPage): void {\n  const lines = page.text.split(\"\\n\");\n\n  let minX: number | undefined = undefined;\n  let minY: number | undefined = undefined;\n  let maxY: number | undefined = undefined;\n\n  // Find margins\n  for (let index = 0; index < lines.length; index++) {\n    const line = lines[index];\n    if (line.trim().length === 0) {\n      continue;\n    }\n\n    // Find first non-whitespace character position (left margin)\n    const x = line.search(/\\S/);\n    if (minX === undefined || x < minX) {\n      minX = x;\n    }\n\n    // First non-empty line (top margin)\n    if (minY === undefined) {\n      minY = index;\n    }\n\n    // Last non-empty line (bottom margin)\n    maxY = index;\n  }\n\n  // If page is entirely empty, just return\n  if (minX === undefined || minY === undefined || maxY === undefined) {\n    page.text = \"\";\n    return;\n  }\n\n  // Remove margins\n  const newLines: string[] = [];\n  for (let index = 0; index < lines.length; index++) {\n    // Skip lines before first content (top margin) or after last content (bottom margin)\n    if (index < minY || index > maxY) {\n      continue;\n    }\n\n    let line = lines[index];\n\n    // Remove trailing whitespace (right margin)\n    line = line.trimEnd();\n\n    // Remove left margin\n    newLines.push(line.slice(minX));\n  }\n\n  page.text = newLines.join(\"\\n\");\n}\n\n/**\n * Detect and remove margins from all pages.\n * Processes each page independently.\n */\nfunction detectAndRemoveMargin(pages: ParsedPage[]): void {\n  for (const page of pages) {\n    detectAndRemoveMarginOnPage(page);\n  }\n}\n\n/**\n * Clean raw text output - removes margins, null characters\n */\nexport function cleanRawText(pages: ParsedPage[], _config: LiteParseConfig): void {\n  // Remove margins (per-page)\n  detectAndRemoveMargin(pages);\n\n  // Remove null characters\n  for (const page of pages) {\n    // eslint-disable-next-line no-control-regex\n    page.text = page.text.replace(/\\u0000/g, \" \");\n  }\n}\n"
  },
  {
    "path": "src/processing/grid.ts",
    "content": "import { PageData } from \"../engines/pdf/interface.js\";\nimport { ParsedPage, LiteParseConfig } from \"../core/types.js\";\nimport { projectPagesToGrid as projectPagesToGridComplete } from \"./gridProjection.js\";\nimport { DEFAULT_CONFIG } from \"../core/config.js\";\n\n/**\n * Projects text items onto a grid for spatial text extraction\n */\nexport async function projectPagesToGrid(\n  pages: PageData[],\n  config?: Partial<LiteParseConfig>\n): Promise<ParsedPage[]> {\n  const fullConfig = {\n    ...DEFAULT_CONFIG,\n    ...config,\n  };\n\n  return projectPagesToGridComplete(pages, fullConfig);\n}\n"
  },
  {
    "path": "src/processing/gridDebugLogger.ts",
    "content": "import { mkdirSync, writeFileSync } from \"fs\";\nimport { mkdir, writeFile } from \"fs/promises\";\nimport { dirname } from \"path\";\nimport { ProjectionTextBox } from \"../core/types.js\";\n\n/**\n * Configuration for grid projection debug logging.\n *\n * When enabled, logs detailed information about how text elements are\n * snapped, anchored, and projected during grid layout. Use filters to\n * narrow output to specific elements you're investigating.\n */\nexport interface GridDebugConfig {\n  /**\n   * Enable debug logging for grid projection.\n   * @defaultValue `false`\n   */\n  enabled: boolean;\n\n  /**\n   * Only log elements whose text contains one of these substrings (case-insensitive).\n   * If empty, all elements are logged.\n   */\n  textFilter?: string[];\n\n  /**\n   * Only log elements on these line indices (0-based within the page).\n   */\n  lineFilter?: number[];\n\n  /**\n   * Only log elements on this page number (1-indexed).\n   */\n  pageFilter?: number;\n\n  /**\n   * Only log elements within this bounding region (PDF coordinates).\n   */\n  regionFilter?: { x1: number; y1: number; x2: number; y2: number };\n\n  /**\n   * Write log output to a file path instead of stderr. If not set, logs to stderr.\n   */\n  outputPath?: string;\n\n  /**\n   * Generate PNG visualizations of the grid projection showing text boxes\n   * color-coded by snap type (left/right/center/floating/flowing) with\n   * anchor lines overlaid.\n   * @defaultValue `false`\n   */\n  visualize?: boolean;\n\n  /**\n   * Directory to save visualization PNGs. Each page produces a file\n   * named `page-{N}-grid.png`.\n   * @defaultValue `\"./debug-output\"`\n   */\n  visualizePath?: string;\n}\n\nexport const DEFAULT_DEBUG_CONFIG: GridDebugConfig = {\n  enabled: false,\n};\n\ntype LogEntry = {\n  phase: string;\n  lineIndex?: number;\n  boxIndex?: number;\n  text?: string;\n  message: string;\n  data?: Record<string, unknown>;\n};\n\n/** A segment of rendered text placed into the output grid. */\nexport interface RenderedSegment {\n  lineIndex: number;\n  /** Character column where this segment starts in the output line. */\n  gridCol: number;\n  text: string;\n  snap: \"left\" | \"right\" | \"center\" | \"floating\" | \"flowing\";\n}\n\n/** Captured data for a single page, used by the grid visualizer. */\nexport interface VisualizerPageData {\n  pageNum: number;\n  /** Rendered text segments with snap type for color coding. */\n  segments: RenderedSegment[];\n  /** Final projected text lines (the actual output). */\n  rawLines: string[];\n}\n\n/**\n * Debug logger for grid projection. Provides targeted logging to trace\n * exactly why specific text elements are projected the way they are.\n *\n * Usage from LiteParse config:\n * ```typescript\n * const parser = new LiteParse({\n *   debug: {\n *     enabled: true,\n *     textFilter: [\"Total\", \"Revenue\"],  // only log elements containing these strings\n *     pageFilter: 2,                      // only page 2\n *     visualize: true,                    // generate PNG overlays\n *   }\n * });\n * ```\n */\nexport class GridDebugLogger {\n  private config: GridDebugConfig;\n  private entries: LogEntry[] = [];\n  private currentPage: number = 0;\n  private writeOutput: (msg: string) => void;\n\n  // Visualization data collection\n  private vizPages: VisualizerPageData[] = [];\n  private currentVizPage?: VisualizerPageData;\n\n  constructor(config: GridDebugConfig) {\n    this.config = config;\n    if (config.outputPath) {\n      // Defer file writing to flush()\n      this.writeOutput = () => {};\n    } else {\n      this.writeOutput = (msg: string) => process.stderr.write(msg + \"\\n\");\n    }\n  }\n\n  get enabled(): boolean {\n    return this.config.enabled;\n  }\n\n  get shouldVisualize(): boolean {\n    return this.config.visualize ?? false;\n  }\n\n  get visualizerPages(): VisualizerPageData[] {\n    return this.vizPages;\n  }\n\n  get debugConfig(): GridDebugConfig {\n    return this.config;\n  }\n\n  setPage(pageNum: number, _width: number, _height: number): void {\n    this.currentPage = pageNum;\n    if (this.config.pageFilter && pageNum !== this.config.pageFilter) {\n      return;\n    }\n    this.emit({ phase: \"page\", message: `=== Page ${pageNum} ===` });\n\n    if (this.shouldVisualize) {\n      this.currentVizPage = {\n        pageNum,\n        segments: [],\n        rawLines: [],\n      };\n      this.vizPages.push(this.currentVizPage);\n    }\n  }\n\n  private isPageFiltered(): boolean {\n    return !!this.config.pageFilter && this.currentPage !== this.config.pageFilter;\n  }\n\n  /** Check if a bbox passes the configured filters */\n  matchesBbox(bbox: ProjectionTextBox, lineIndex?: number): boolean {\n    if (!this.config.enabled) return false;\n    if (this.isPageFiltered()) return false;\n\n    if (this.config.textFilter?.length) {\n      const text = bbox.str.toLowerCase();\n      if (!this.config.textFilter.some((f) => text.includes(f.toLowerCase()))) {\n        return false;\n      }\n    }\n\n    if (this.config.lineFilter?.length && lineIndex !== undefined) {\n      if (!this.config.lineFilter.includes(lineIndex)) {\n        return false;\n      }\n    }\n\n    if (this.config.regionFilter) {\n      const r = this.config.regionFilter;\n      if (bbox.x + bbox.w < r.x1 || bbox.x > r.x2 || bbox.y + bbox.h < r.y1 || bbox.y > r.y2) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  /** Log which block a line range was assigned to */\n  logBlock(blockIndex: number, start: number, end: number): void {\n    if (!this.config.enabled || this.isPageFiltered()) return;\n    this.emit({\n      phase: \"blocks\",\n      message: `Block ${blockIndex}: lines ${start}-${end - 1}`,\n    });\n  }\n\n  /** Log flowing text classification */\n  logFlowingBlock(start: number, end: number): void {\n    if (!this.config.enabled || this.isPageFiltered()) return;\n    this.emit({\n      phase: \"flowing\",\n      message: `Block lines ${start}-${end - 1} classified as flowing text`,\n    });\n  }\n\n  /** Log non-flowing block (no-op, only used for symmetry with logFlowingBlock) */\n  logStructuredBlock(_start: number, _end: number): void {}\n\n  /** Log flowing line detection */\n  logFlowingLine(lineIndex: number, reason: string): void {\n    if (!this.config.enabled || this.isPageFiltered()) return;\n    if (this.config.lineFilter?.length && !this.config.lineFilter.includes(lineIndex)) return;\n    this.emit({\n      phase: \"flowing\",\n      lineIndex,\n      message: `Line ${lineIndex} marked flowing: ${reason}`,\n    });\n  }\n\n  /** Log anchor extraction results for a block */\n  logAnchors(\n    anchorLeft: Record<number, ProjectionTextBox[]>,\n    anchorRight: Record<number, ProjectionTextBox[]>,\n    anchorCenter: Record<number, ProjectionTextBox[]>\n  ): void {\n    if (!this.config.enabled || this.isPageFiltered()) return;\n\n    const leftKeys = Object.keys(anchorLeft).map(Number);\n    const rightKeys = Object.keys(anchorRight).map(Number);\n    const centerKeys = Object.keys(anchorCenter).map(Number);\n\n    this.emit({\n      phase: \"anchors\",\n      message: `Anchors: left=[${leftKeys.join(\", \")}] right=[${rightKeys.join(\", \")}] center=[${centerKeys.join(\", \")}]`,\n    });\n\n    // Log which elements are in each anchor, but only if they match filters\n    for (const key of leftKeys) {\n      const items = anchorLeft[key];\n      const matchingItems = this.config.textFilter?.length\n        ? items.filter((b) => this.matchesBbox(b))\n        : items;\n      if (matchingItems.length > 0) {\n        this.emit({\n          phase: \"anchors\",\n          message: `  left@${key}: ${matchingItems.map((b) => `\"${b.str.substring(0, 30)}\" (x=${b.x.toFixed(1)}, y=${b.y.toFixed(1)})`).join(\", \")}`,\n        });\n      }\n    }\n    for (const key of rightKeys) {\n      const items = anchorRight[key];\n      const matchingItems = this.config.textFilter?.length\n        ? items.filter((b) => this.matchesBbox(b))\n        : items;\n      if (matchingItems.length > 0) {\n        this.emit({\n          phase: \"anchors\",\n          message: `  right@${key}: ${matchingItems.map((b) => `\"${b.str.substring(0, 30)}\" (x=${b.x.toFixed(1)}, y=${b.y.toFixed(1)})`).join(\", \")}`,\n        });\n      }\n    }\n    for (const key of centerKeys) {\n      const items = anchorCenter[key];\n      const matchingItems = this.config.textFilter?.length\n        ? items.filter((b) => this.matchesBbox(b))\n        : items;\n      if (matchingItems.length > 0) {\n        this.emit({\n          phase: \"anchors\",\n          message: `  center@${key}: ${matchingItems.map((b) => `\"${b.str.substring(0, 30)}\" (x=${b.x.toFixed(1)}, y=${b.y.toFixed(1)})`).join(\", \")}`,\n        });\n      }\n    }\n  }\n\n  /** Log snap assignment for a bbox */\n  logSnapAssignment(bbox: ProjectionTextBox, lineIndex: number, boxIndex: number): void {\n    if (!this.matchesBbox(bbox, lineIndex)) return;\n    this.emit({\n      phase: \"snap\",\n      lineIndex,\n      boxIndex,\n      text: bbox.str,\n      message: `\"${bbox.str.substring(0, 40)}\" snap=${bbox.snap ?? \"none\"} leftAnchor=${bbox.leftAnchor ?? \"-\"} rightAnchor=${bbox.rightAnchor ?? \"-\"} centerAnchor=${bbox.centerAnchor ?? \"-\"} forceUnsnapped=${bbox.forceUnsnapped ?? false}`,\n      data: {\n        x: round2(bbox.x),\n        y: round2(bbox.y),\n        w: round2(bbox.w),\n        h: round2(bbox.h),\n        shouldSpace: bbox.shouldSpace,\n      },\n    });\n  }\n\n  /** Capture a rendered text segment for visualization. */\n  captureRender(\n    lineIndex: number,\n    gridCol: number,\n    text: string,\n    snap: \"left\" | \"right\" | \"center\" | \"floating\" | \"flowing\"\n  ): void {\n    if (!this.currentVizPage) return;\n    this.currentVizPage.segments.push({ lineIndex, gridCol, text, snap });\n  }\n\n  /** Capture the final raw lines after projection completes for this page. */\n  captureRawLines(rawLines: string[]): void {\n    if (!this.currentVizPage) return;\n    this.currentVizPage.rawLines = Array.from(\n      { length: rawLines.length },\n      (_, i) => rawLines[i] ?? \"\"\n    );\n  }\n\n  /** Log the rendering of a bbox to a target column position */\n  logRender(bbox: ProjectionTextBox, lineIndex: number, targetX: number, reason: string): void {\n    if (!this.matchesBbox(bbox, lineIndex)) return;\n    this.emit({\n      phase: \"render\",\n      lineIndex,\n      text: bbox.str,\n      message: `\"${bbox.str.substring(0, 40)}\" → col ${targetX} (${reason})`,\n      data: {\n        pdfX: round2(bbox.x),\n        snap: bbox.snap ?? \"none\",\n        shouldSpace: bbox.shouldSpace,\n      },\n    });\n  }\n\n  /** Log forward anchor updates */\n  logForwardAnchor(\n    type: \"left\" | \"right\" | \"center\" | \"floating\",\n    pdfX: number,\n    gridCol: number\n  ): void {\n    if (!this.config.enabled || this.isPageFiltered()) return;\n    // Only log if no text filter (forward anchors aren't bbox-specific) or if we've been logging\n    if (this.config.textFilter?.length) return;\n    this.emit({\n      phase: \"forward-anchor\",\n      message: `${type}@${round2(pdfX)} → col ${gridCol}`,\n    });\n  }\n\n  /** Log duplicate resolution for multi-anchor elements */\n  logDuplicateResolution(bbox: ProjectionTextBox, resolvedTo: string): void {\n    if (!this.matchesBbox(bbox)) return;\n    this.emit({\n      phase: \"dedup\",\n      text: bbox.str,\n      message: `\"${bbox.str.substring(0, 40)}\" multi-anchor resolved to ${resolvedTo} (left=${bbox.leftAnchor ?? \"-\"} right=${bbox.rightAnchor ?? \"-\"} center=${bbox.centerAnchor ?? \"-\"})`,\n    });\n  }\n\n  /** Log line composition (the full set of bboxes on a line) */\n  logLineComposition(lineIndex: number, line: ProjectionTextBox[]): void {\n    if (!this.config.enabled || this.isPageFiltered()) return;\n    if (this.config.lineFilter?.length && !this.config.lineFilter.includes(lineIndex)) return;\n    // If text filter is set, only log lines that contain a matching bbox\n    if (this.config.textFilter?.length) {\n      if (!line.some((b) => this.matchesBbox(b, lineIndex))) return;\n    }\n    const items = line.map((b) => `\"${b.str.substring(0, 20)}\"@(${round2(b.x)},${round2(b.y)})`);\n    this.emit({\n      phase: \"lines\",\n      lineIndex,\n      message: `Line ${lineIndex} [${line.length} items]: ${items.join(\"  \")}`,\n    });\n  }\n\n  private emit(entry: LogEntry): void {\n    this.entries.push(entry);\n    if (!this.config.outputPath) {\n      const prefix = `[grid-debug][${entry.phase}]`;\n      const loc =\n        entry.lineIndex !== undefined\n          ? ` L${entry.lineIndex}${entry.boxIndex !== undefined ? `:${entry.boxIndex}` : \"\"}`\n          : \"\";\n      let line = `${prefix}${loc} ${entry.message}`;\n      if (entry.data) {\n        line += ` ${JSON.stringify(entry.data)}`;\n      }\n      this.writeOutput(line);\n    }\n  }\n\n  private formatEntries(): string {\n    return (\n      this.entries\n        .map((entry) => {\n          const prefix = `[${entry.phase}]`;\n          const loc =\n            entry.lineIndex !== undefined\n              ? ` L${entry.lineIndex}${entry.boxIndex !== undefined ? `:${entry.boxIndex}` : \"\"}`\n              : \"\";\n          let line = `${prefix}${loc} ${entry.message}`;\n          if (entry.data) {\n            line += ` ${JSON.stringify(entry.data)}`;\n          }\n          return line;\n        })\n        .join(\"\\n\") + \"\\n\"\n    );\n  }\n\n  /** Synchronous flush of log entries to file. */\n  flushSync(): void {\n    if (!this.config.outputPath || this.entries.length === 0) return;\n    mkdirSync(dirname(this.config.outputPath), { recursive: true });\n    writeFileSync(this.config.outputPath, this.formatEntries(), \"utf-8\");\n    this.entries = [];\n  }\n\n  /** Flush entries to file if outputPath is configured */\n  async flush(): Promise<void> {\n    if (!this.config.outputPath || this.entries.length === 0) return;\n    await mkdir(dirname(this.config.outputPath), { recursive: true });\n    await writeFile(this.config.outputPath, this.formatEntries(), \"utf-8\");\n    this.entries = [];\n  }\n}\n\n/** No-op logger that skips all checks. Use when debug is disabled. */\nclass NoopGridDebugLogger extends GridDebugLogger {\n  constructor() {\n    super({ enabled: false });\n  }\n  override get enabled(): boolean {\n    return false;\n  }\n  override get shouldVisualize(): boolean {\n    return false;\n  }\n  override matchesBbox(): boolean {\n    return false;\n  }\n  override setPage(): void {}\n  override logBlock(): void {}\n  override logFlowingBlock(): void {}\n  override logStructuredBlock(): void {}\n  override logFlowingLine(): void {}\n  override logAnchors(): void {}\n  override logSnapAssignment(): void {}\n  override captureRender(): void {}\n  override captureRawLines(): void {}\n  override logRender(): void {}\n  override logForwardAnchor(): void {}\n  override logDuplicateResolution(): void {}\n  override logLineComposition(): void {}\n  override flushSync(): void {}\n  override async flush(): Promise<void> {}\n}\n\n/** Singleton no-op instance for zero-overhead when debug is off */\nexport const NOOP_LOGGER = new NoopGridDebugLogger();\n\nexport function createGridDebugLogger(config?: GridDebugConfig): GridDebugLogger {\n  if (!config?.enabled) return NOOP_LOGGER;\n  return new GridDebugLogger(config);\n}\n\nfunction round2(n: number): number {\n  return Math.round(n * 100) / 100;\n}\n"
  },
  {
    "path": "src/processing/gridProjection.test.ts",
    "content": "import { expect, describe, it } from \"vitest\";\nimport { bboxToLine, projectPagesToGrid, projectToGrid } from \"./gridProjection\";\nimport { ProjectionTextBox } from \"../core/types\";\nimport { DEFAULT_CONFIG } from \"../core/config\";\nimport { NOOP_LOGGER } from \"./gridDebugLogger\";\n\ndescribe(\"test bboxToLine\", () => {\n  it(\"test  same line that can merge\", () => {\n    const textBbox = [\n      { str: \"Hello\", x: 0, y: 10, w: 50, h: 12, strLength: 5 },\n      { str: \" World\", x: 50, y: 10, w: 55, h: 12, strLength: 6 },\n    ];\n    const medianWidth = 10;\n    const medianHeight = 12;\n    const expectedOutput = [\n      [\n        {\n          str: \"Hello World\",\n          x: 0,\n          y: 10,\n          w: 105,\n          h: 12,\n          strLength: 11,\n          pageBbox: { x: 0, y: 10, w: 105, h: 12 },\n        },\n      ],\n    ];\n\n    const result = bboxToLine(textBbox, medianWidth, medianHeight);\n    expect(result).toStrictEqual(expectedOutput);\n  });\n\n  it(\"test same line that cannot merge (gap too large)\", () => {\n    const textBbox = [\n      { str: \"Hello\", x: 0, y: 10, w: 50, h: 12, strLength: 5 },\n      { str: \"World\", x: 100, y: 10, w: 50, h: 12, strLength: 5 },\n    ];\n    const medianWidth = 10;\n    const medianHeight = 12;\n    const expectedOutput = [\n      [\n        { str: \"Hello\", x: 0, y: 10, w: 50, h: 12, strLength: 5 },\n        { str: \"World\", x: 100, y: 10, w: 50, h: 12, strLength: 5 },\n      ],\n    ];\n\n    const result = bboxToLine(textBbox, medianWidth, medianHeight);\n    expect(result).toStrictEqual(expectedOutput);\n  });\n\n  it(\"test boxes on different lines\", () => {\n    const textBbox = [\n      { str: \"Line1\", x: 0, y: 10, w: 50, h: 12, strLength: 5 },\n      { str: \"Line2\", x: 0, y: 30, w: 50, h: 12, strLength: 5 },\n    ];\n    const medianWidth = 10;\n    const medianHeight = 12;\n    const expectedOutput = [\n      [{ str: \"Line1\", x: 0, y: 10, w: 50, h: 12, strLength: 5 }],\n      [{ str: \"Line2\", x: 0, y: 30, w: 50, h: 12, strLength: 5 }],\n    ];\n\n    const result = bboxToLine(textBbox, medianWidth, medianHeight);\n    expect(result).toStrictEqual(expectedOutput);\n  });\n\n  it(\"test same y/h but small negative xDelta\", () => {\n    const textBbox = [\n      { str: \"AB\", x: 0, y: 5, w: 20.3, h: 10, strLength: 2 },\n      { str: \"CD\", x: 20.1, y: 5, w: 20, h: 10, strLength: 2 },\n    ];\n    const medianWidth = 10;\n    const medianHeight = 12;\n    const expectedOutput = [\n      [\n        {\n          str: \"ABCD\",\n          x: 0,\n          y: 5,\n          w: 40.1,\n          h: 10,\n          strLength: 4,\n          pageBbox: { x: 0, y: 5, w: 40.1, h: 10 },\n        },\n      ],\n    ];\n\n    const result = bboxToLine(textBbox, medianWidth, medianHeight);\n    expect(result).toStrictEqual(expectedOutput);\n  });\n\n  it(\"test matching markup that can merge\", () => {\n    const textBbox = [\n      {\n        str: \"Bold\",\n        x: 0,\n        y: 0,\n        w: 40,\n        h: 10,\n        strLength: 4,\n        markup: { highlight: \"no\", underline: true, squiggly: false, strikeout: false },\n      },\n      {\n        str: \"Text\",\n        x: 40,\n        y: 0,\n        w: 40,\n        h: 10,\n        strLength: 4,\n        markup: { highlight: \"no\", underline: true, squiggly: false, strikeout: false },\n      },\n    ];\n    const medianWidth = 10;\n    const medianHeight = 12;\n    const expectedOutput = [\n      [\n        {\n          str: \"BoldText\",\n          x: 0,\n          y: 0,\n          w: 80,\n          h: 10,\n          strLength: 8,\n          markup: { highlight: \"no\", underline: true, squiggly: false, strikeout: false },\n          pageBbox: { x: 0, y: 0, w: 80, h: 10 },\n        },\n      ],\n    ];\n\n    const result = bboxToLine(textBbox, medianWidth, medianHeight);\n    expect(result).toStrictEqual(expectedOutput);\n  });\n\n  it(\"test mismatched markup that cannot merge\", () => {\n    const textBbox = [\n      {\n        str: \"A\",\n        x: 0,\n        y: 0,\n        w: 10,\n        h: 10,\n        strLength: 1,\n        markup: { highlight: \"yes\", underline: false, squiggly: false, strikeout: false },\n      },\n      {\n        str: \"B\",\n        x: 10,\n        y: 0,\n        w: 10,\n        h: 10,\n        strLength: 1,\n        markup: { highlight: \"no\", underline: false, squiggly: false, strikeout: false },\n      },\n    ];\n    const medianWidth = 10;\n    const medianHeight = 12;\n    const expectedOutput = [\n      [\n        {\n          str: \"A\",\n          x: 0,\n          y: 0,\n          w: 10,\n          h: 10,\n          strLength: 1,\n          markup: { highlight: \"yes\", underline: false, squiggly: false, strikeout: false },\n        },\n        {\n          str: \"B\",\n          x: 10,\n          y: 0,\n          w: 10,\n          h: 10,\n          strLength: 1,\n          markup: { highlight: \"no\", underline: false, squiggly: false, strikeout: false },\n        },\n      ],\n    ];\n\n    const result = bboxToLine(textBbox, medianWidth, medianHeight);\n    expect(result).toStrictEqual(expectedOutput);\n  });\n\n  it(\"test unsorted -> sorted\", () => {\n    const textBbox = [\n      { str: \"C\", x: 20, y: 0, w: 10, h: 10, strLength: 1 },\n      { str: \"A\", x: 0, y: 0, w: 10, h: 10, strLength: 1 },\n      { str: \"B\", x: 10, y: 0, w: 10, h: 10, strLength: 1 },\n    ];\n    const medianWidth = 10;\n    const medianHeight = 12;\n    const expectedOutput = [\n      [\n        {\n          str: \"ABC\",\n          x: 0,\n          y: 0,\n          w: 30,\n          h: 10,\n          strLength: 3,\n          pageBbox: { x: 0, y: 0, w: 30, h: 10 },\n        },\n      ],\n    ];\n\n    const result = bboxToLine(textBbox, medianWidth, medianHeight);\n    expect(result).toStrictEqual(expectedOutput);\n  });\n\n  it(\"test empty input\", () => {\n    const textBbox: ProjectionTextBox[] = [];\n    const medianWidth = 10;\n    const medianHeight = 12;\n    const expectedOutput: ProjectionTextBox[][] = [];\n\n    const result = bboxToLine(textBbox, medianWidth, medianHeight);\n    expect(result).toStrictEqual(expectedOutput);\n  });\n\n  it(\"uses representative line height for bullet-line spacing\", () => {\n    const textBbox = [\n      { str: \"Recommendation\", x: 7.68, y: 6.24, w: 66.24, h: 6.24, strLength: 14 },\n      { str: \"summary\", x: 79.68, y: 8.16, w: 32.64, h: 5.76, strLength: 7 },\n      { str: \"-\", x: 8.16, y: 30.72, w: 2.4, h: 0.48, strLength: 1 },\n      { str: \"Primary\", x: 17.28, y: 26.88, w: 32.64, h: 7.68, strLength: 7 },\n      { str: \"choice:\", x: 55.2, y: 26.88, w: 32.16, h: 6.24, strLength: 7 },\n      { str: \"Apache\", x: 93.6, y: 26.88, w: 28.32, h: 7.68, strLength: 6 },\n      { str: \"ECharts\", x: 127.68, y: 26.88, w: 32.64, h: 6.24, strLength: 7 },\n    ];\n\n    const result = bboxToLine(textBbox, 4.32, 6.24);\n    const renderedLines = result.map((line) => line.map((bbox) => bbox.str).join(\" \"));\n\n    expect(renderedLines).toStrictEqual([\n      \"Recommendation summary\",\n      \"\",\n      \"- Primary choice: Apache ECharts\",\n    ]);\n  });\n\n  it(\"preserves blank lines for regular non-bulleted text\", () => {\n    const textBbox = [\n      { str: \"Heading\", x: 10, y: 10, w: 42, h: 6, strLength: 7 },\n      { str: \"First\", x: 10, y: 28, w: 26, h: 6, strLength: 5 },\n      { str: \"paragraph\", x: 40, y: 28, w: 44, h: 6, strLength: 9 },\n      { str: \"Second\", x: 10, y: 34, w: 34, h: 6, strLength: 6 },\n      { str: \"line\", x: 48, y: 34, w: 20, h: 6, strLength: 4 },\n    ];\n\n    const result = bboxToLine(textBbox, 5, 6);\n    const renderedLines = result.map((line) => line.map((bbox) => bbox.str).join(\" \"));\n\n    expect(renderedLines).toStrictEqual([\"Heading\", \"\", \"First paragraph\", \"Second line\"]);\n  });\n});\n\ndescribe(\"test projectToGrid\", () => {\n  it(\"test simple single-column text\", () => {\n    const config = { ...DEFAULT_CONFIG, preserveLayoutAlignmentAcrossPages: false };\n    const page = {\n      pageNum: 1,\n      width: 612,\n      height: 792,\n      textItems: [],\n      images: [],\n    };\n    const projectionBoxes = [\n      { str: \"Hello\", x: 10, y: 100, w: 50, h: 12, r: 0, strLength: 5 },\n      { str: \"World\", x: 10, y: 115, w: 50, h: 12, r: 0, strLength: 5 },\n    ];\n    const prevAnchors = { forwardAnchorLeft: {}, forwardAnchorRight: {}, forwardAnchorCenter: {} };\n    const totalPages = 1;\n    const expectedOutput = {\n      text: \" Hello\\n World\",\n      prevAnchors: {\n        forwardAnchorLeft: {\n          \"10\": 1,\n        },\n        forwardAnchorRight: {},\n        forwardAnchorCenter: {},\n      },\n    };\n    const result = projectToGrid(\n      config,\n      page,\n      projectionBoxes,\n      prevAnchors,\n      totalPages,\n      NOOP_LOGGER\n    );\n    expect(result).toStrictEqual(expectedOutput);\n  });\n\n  it(\"test two-column layout\", () => {\n    const config = { ...DEFAULT_CONFIG, preserveLayoutAlignmentAcrossPages: false };\n    const page = {\n      pageNum: 1,\n      width: 612,\n      height: 792,\n      textItems: [],\n      images: [],\n    };\n    const projectionBoxes = [\n      { str: \"Name\", x: 10, y: 100, w: 40, h: 12, r: 0, strLength: 4 },\n      { str: \"Age\", x: 300, y: 100, w: 30, h: 12, r: 0, strLength: 3 },\n      { str: \"Alice\", x: 10, y: 115, w: 50, h: 12, r: 0, strLength: 5 },\n      { str: \"30\", x: 300, y: 115, w: 20, h: 12, r: 0, strLength: 2 },\n    ];\n    const prevAnchors = {\n      forwardAnchorLeft: {\n        \"10\": 1,\n        \"300\": 11,\n      },\n      forwardAnchorRight: {},\n      forwardAnchorCenter: {},\n    };\n    const totalPages = 1;\n    const expectedOutput = {\n      text: \" Name      Age\\n Alice     30\",\n      prevAnchors: prevAnchors,\n    };\n    const result = projectToGrid(\n      config,\n      page,\n      projectionBoxes,\n      prevAnchors,\n      totalPages,\n      NOOP_LOGGER\n    );\n    expect(result).toStrictEqual(expectedOutput);\n  });\n\n  it(\"test dot-garbage filtering\", () => {\n    const config = { ...DEFAULT_CONFIG, preserveLayoutAlignmentAcrossPages: false };\n    const page = {\n      pageNum: 1,\n      width: 612,\n      height: 792,\n      textItems: [],\n      images: [],\n    };\n    const projectionBoxes = [\n      ...Array(110).fill({ str: \"...\", x: 0, y: 0, w: 10, h: 10, r: 0, strLength: 3 }),\n      { str: \"Revenue\", x: 10, y: 100, w: 70, h: 12, r: 0, strLength: 7 },\n      { str: \"500\", x: 300, y: 100, w: 30, h: 12, r: 0, strLength: 3 },\n    ];\n    const prevAnchors = { forwardAnchorLeft: {}, forwardAnchorRight: {}, forwardAnchorCenter: {} };\n    const totalPages = 1;\n    const expectedOutput = {\n      text: \" Revenue    500\",\n      prevAnchors: prevAnchors,\n    };\n    const result = projectToGrid(\n      config,\n      page,\n      projectionBoxes,\n      prevAnchors,\n      totalPages,\n      NOOP_LOGGER\n    );\n    expect(result).toStrictEqual(expectedOutput);\n  });\n});\n\nconst mockPageData = [\n  {\n    pageNum: 1,\n    width: 595,\n    height: 842,\n    textItems: [\n      {\n        str: \"Hello World\",\n        x: 50,\n        y: 750,\n        width: 120,\n        height: 12,\n        w: 120,\n        h: 12,\n        fontName: \"Arial\",\n        fontSize: 12,\n      },\n    ],\n    images: [\n      {\n        x: 100,\n        y: 600,\n        width: 200,\n        height: 150,\n        type: \"jpeg\",\n        scaleFactor: 1.0,\n      },\n    ],\n  },\n  {\n    pageNum: 2,\n    width: 595,\n    height: 842,\n    textItems: [\n      {\n        str: \"Section 2\",\n        x: 50,\n        y: 800,\n        width: 90,\n        height: 16,\n        w: 90,\n        h: 16,\n        fontName: \"Times New Roman\",\n        fontSize: 16,\n        r: 0,\n      },\n      {\n        str: \"Some body text on page 2\",\n        x: 50,\n        y: 770,\n        width: 300,\n        height: 12,\n        w: 300,\n        h: 12,\n        fontName: \"Times New Roman\",\n        fontSize: 12,\n      },\n    ],\n    images: [],\n  },\n  {\n    pageNum: 3,\n    width: 595,\n    height: 842,\n    textItems: [\n      {\n        str: \"Rotated Text\",\n        x: 400,\n        y: 400,\n        width: 100,\n        height: 12,\n        w: 100,\n        h: 12,\n        fontName: \"Arial\",\n        fontSize: 12,\n        r: 90,\n        rx: 400,\n        ry: 400,\n      },\n    ],\n    images: [\n      {\n        x: 50,\n        y: 500,\n        width: 300,\n        height: 200,\n        type: \"png\",\n        scaleFactor: 1.5,\n        originalOrientationAngle: 0,\n        coords: { x: 50, y: 500, w: 300, h: 200 },\n      },\n    ],\n  },\n];\n\ndescribe(\"test projectPagesToGrid\", () => {\n  it(\"test pages projection\", async () => {\n    const config = { ...DEFAULT_CONFIG, preserveLayoutAlignmentAcrossPages: false };\n    const expectedOutput = [\n      {\n        pageNum: 1,\n        width: 595,\n        height: 842,\n        text: \"Hello World\",\n        textItems: [\n          {\n            str: \"Hello World\",\n            x: 50,\n            y: 750,\n            width: 120,\n            height: 12,\n            w: 120,\n            h: 12,\n            fontName: \"Arial\",\n            fontSize: 12,\n          },\n        ],\n        boundingBoxes: [],\n      },\n      {\n        pageNum: 2,\n        width: 595,\n        height: 842,\n        text: \"Some body text on page 2\\n\\nSection 2\",\n        textItems: [\n          {\n            str: \"Section 2\",\n            x: 50,\n            y: 800,\n            width: 90,\n            height: 16,\n            w: 90,\n            h: 16,\n            fontName: \"Times New Roman\",\n            fontSize: 16,\n            r: 0,\n          },\n          {\n            str: \"Some body text on page 2\",\n            x: 50,\n            y: 770,\n            width: 300,\n            height: 12,\n            w: 300,\n            h: 12,\n            fontName: \"Times New Roman\",\n            fontSize: 12,\n          },\n        ],\n        boundingBoxes: [],\n      },\n      {\n        pageNum: 3,\n        width: 595,\n        height: 842,\n        text: \"Rotated Text\",\n        textItems: [\n          {\n            str: \"Rotated Text\",\n            x: 400,\n            y: 400,\n            width: 100,\n            height: 12,\n            w: 100,\n            h: 12,\n            fontName: \"Arial\",\n            fontSize: 12,\n            r: 90,\n            rx: 400,\n            ry: 400,\n          },\n        ],\n        boundingBoxes: [],\n      },\n    ];\n    const result = await projectPagesToGrid(mockPageData, config);\n    expect(result).toStrictEqual(expectedOutput);\n  });\n});\n"
  },
  {
    "path": "src/processing/gridProjection.ts",
    "content": "import { strToSubscriptString, strToPostScript } from \"./textUtils.js\";\nimport { buildBbox } from \"./bbox.js\";\nimport { cleanRawText } from \"./cleanText.js\";\nimport { ProjectionTextBox, Coordinates, LiteParseConfig, ParsedPage } from \"../core/types.js\";\nimport { PageData } from \"../engines/pdf/interface.js\";\n\nimport { applyMarkupTags } from \"./markupUtils.js\";\nimport { GridDebugLogger, createGridDebugLogger } from \"./gridDebugLogger.js\";\nimport { renderAllVisualizations } from \"./gridVisualizer.js\";\n\n// Minimum spaces between unsnapped bboxes (likely justified text\nconst FLOATING_SPACES = 2;\n// Minimum spaces between snapped columns\nconst COLUMN_SPACES = 4;\n\n// --- Flowing text detection thresholds ---\n// Max total anchors (left+right+center) before block is considered structured\nconst FLOWING_MAX_TOTAL_ANCHORS = 4;\n// Max left anchors before block is considered structured\nconst FLOWING_MAX_LEFT_ANCHORS = 3;\n// Minimum non-empty lines required to classify a block\nconst FLOWING_MIN_LINES = 3;\n// Fraction of page width a line must span to count as \"wide\"\nconst FLOWING_WIDE_LINE_RATIO = 0.5;\n// Fraction of lines that must be wide for a block to be flowing\nconst FLOWING_WIDE_LINE_THRESHOLD = 0.6;\n// Multiplier on median char width for column gap detection\nconst FLOWING_COLUMN_GAP_MULTIPLIER = 4;\n// Minimum items on a line to be classified as flowing in per-line detection\nconst FLOWING_MIN_LINE_ITEMS = 3;\n// Height multiplier for word-break space threshold in flowing text\nconst FLOWING_SPACE_HEIGHT_RATIO = 0.15;\n// Minimum absolute space threshold in flowing text\nconst FLOWING_SPACE_MIN_THRESHOLD = 0.3;\n// Maximum indent (in character widths) for flowing text\nconst FLOWING_MAX_INDENT = 8;\n\ntype Snap = {\n  bbox: ProjectionTextBox;\n  lineIndex: number;\n  boxIndex: number;\n};\n\ntype Anchor = {\n  [key: number]: ProjectionTextBox[];\n};\n\ntype Anchors = {\n  anchorLeft: Anchor;\n  anchorRight: Anchor;\n  anchorCenter: Anchor;\n};\n\ntype ForwardAnchor = { [key: string]: number };\n\ntype PrevAnchors = {\n  forwardAnchorLeft: ForwardAnchor;\n  forwardAnchorCenter: ForwardAnchor;\n  forwardAnchorRight: ForwardAnchor;\n};\n\ntype PageForwardAnchors = {\n  left: ForwardAnchor;\n  right: ForwardAnchor;\n  center: ForwardAnchor;\n  floating: ForwardAnchor;\n};\n\ntype SnapMaps = {\n  left: number[];\n  right: number[];\n  center: number[];\n  floating: number[];\n};\n\ntype LineRange = {\n  start: number;\n  end: number;\n};\n\ntype TextBoxSize = {\n  width: number;\n  height: number;\n};\n\ntype LineMetrics = {\n  top: number;\n  bottom: number;\n  height: number;\n};\n\nfunction roundAnchor(anchor: number): number {\n  // group anchor x-coord by nearest 1/4 unit\n  return Math.round(anchor * 4) / 4;\n}\n\nfunction getRepresentativeLineMetrics(\n  line: ProjectionTextBox[],\n  globalMedianHeight: number\n): LineMetrics {\n  const minRepresentativeHeight = globalMedianHeight * 0.5;\n  const representativeItems = line.filter((bbox) => bbox.h >= minRepresentativeHeight);\n  const items = representativeItems.length > 0 ? representativeItems : line;\n\n  const top = Math.min(...items.map((bbox) => bbox.y));\n  const bottom = Math.max(...items.map((bbox) => bbox.y + bbox.h));\n\n  return {\n    top,\n    bottom,\n    height: bottom - top,\n  };\n}\n\n// 2pt @ PDF 72 DPI -> 8px @ 300DPI\nconst SMALL_FONT_SIZE_THRESHOLD = 2;\n\nfunction isSmallTextLine(line: ProjectionTextBox[]): boolean {\n  // check for line where >50% of the text is very small\n  const smallText = line.filter((item) => item.h < SMALL_FONT_SIZE_THRESHOLD);\n  if (smallText.length / line.length > 0.5) {\n    return true;\n  }\n  return false;\n}\n\nfunction filterUnprojectableText(\n  config: LiteParseConfig,\n  line: ProjectionTextBox[]\n): ProjectionTextBox[] {\n  // Filter text items that would break projection (e.g., very small text)\n  if (line.length === 0) {\n    return line;\n  }\n\n  let filteredLine = line;\n  if (!config.preserveVerySmallText && isSmallTextLine(line)) {\n    // remove very small text lines\n    filteredLine = filteredLine.filter((item) => item.h >= SMALL_FONT_SIZE_THRESHOLD);\n  }\n  return filteredLine;\n}\n\nfunction canSnapLine(config: LiteParseConfig, line: ProjectionTextBox[]): boolean {\n  // force lines that will likely break projection to be unsnapped floating text\n  // currently this includes:\n  //   - lines of entirely small text\n  //\n  // NOTE: this assumes undesirable text has already been filtered before projection\n  // (i.e. parse mode based removal of text should be done before this in filterUnprojectableText())\n  if (line.length === 0) {\n    return true;\n  }\n\n  if (!config.preserveVerySmallText && isSmallTextLine(line)) {\n    return false;\n  }\n  return true;\n}\n\nfunction fixSparseBlocks(blocks: LineRange[], rawLines: string[]) {\n  // compress whitespace in blocks containing very sparse lines (>80% whitespace)\n  const regexp = new RegExp(`\\\\s{${COLUMN_SPACES},}`, \"g\");\n  for (const block of blocks) {\n    let total = 0;\n    let whitespace = 0;\n    for (let i = block.start; i < block.end; ++i) {\n      if (!rawLines[i]) {\n        continue;\n      }\n      rawLines[i] = rawLines[i].trimEnd();\n      const line = rawLines[i];\n      if (line.length === 0) {\n        continue;\n      }\n      total += line.length;\n      whitespace += line.match(/\\s/g)?.length || 0;\n    }\n    if (total >= 500 && whitespace / total > 0.8) {\n      for (let i = block.start; i < block.end; ++i) {\n        const line = rawLines[i];\n        if (!line || line.length === 0) {\n          continue;\n        }\n        rawLines[i] = line.replace(regexp, \" \".repeat(FLOATING_SPACES));\n      }\n    }\n  }\n}\n\nfunction extractAnchorsPointsFromLines(lines: ProjectionTextBox[][], page: PageData): Anchors {\n  const pageHeight = page.height;\n\n  const anchorLeft: Anchor = {};\n  const anchorRight: Anchor = {};\n  const anchorCenter: Anchor = {};\n\n  for (const line of lines) {\n    for (const bbox of line) {\n      let anchor = roundAnchor(bbox.x);\n      if (!anchorLeft[anchor]) {\n        anchorLeft[anchor] = [];\n      }\n      anchorLeft[anchor].push(bbox);\n\n      anchor = roundAnchor(bbox.x + bbox.w);\n      if (!anchorRight[anchor]) {\n        anchorRight[anchor] = [];\n      }\n      anchorRight[anchor].push(bbox);\n\n      const center = Math.round(bbox.x + bbox.w / 2);\n      if (!anchorCenter[center]) {\n        anchorCenter[center] = [];\n      }\n      anchorCenter[center].push(bbox);\n    }\n  }\n\n  function deltaMin(collection: Anchor, delta: number) {\n    for (const anchor in collection) {\n      const maxDelta = pageHeight * delta;\n      for (let i = 0; i < collection[anchor].length; i++) {\n        let shouldKeep = false;\n        if (i > 0) {\n          if (collection[anchor][i].y - collection[anchor][i - 1].y < maxDelta) {\n            shouldKeep = true;\n          }\n        }\n        if (i < collection[anchor].length - 1) {\n          if (collection[anchor][i + 1].y - collection[anchor][i].y < maxDelta) {\n            shouldKeep = true;\n          }\n        }\n\n        if (!shouldKeep) {\n          collection[anchor].splice(i--, 1);\n        }\n      }\n    }\n  }\n\n  // Group nearby anchors FIRST to merge items at similar positions\n  // This ensures deltaMin operates on combined groups, not isolated items\n  group(anchorLeft);\n  group(anchorRight);\n  group(anchorCenter);\n\n  deltaMin(anchorRight, 0.17);\n  deltaMin(anchorLeft, 0.2);\n  deltaMin(anchorCenter, 0.05);\n\n  function intercept(collection: Anchor) {\n    for (const anchor in collection) {\n      let shouldKeep = false;\n      for (let i = 0; i < collection[anchor].length; i++) {\n        if (i > 0) {\n          let intercept = false;\n          // check intercept\n          const a1 = collection[anchor][i - 1];\n          const a2 = collection[anchor][i];\n          for (const line of lines) {\n            if (line.length > 0 && line[0].y > a1.y && line[0].y < a2.y) {\n              for (const item of line) {\n                if (item.x < parseInt(anchor) && item.x + item.w > parseInt(anchor)) {\n                  intercept = true;\n                  break;\n                }\n              }\n              if (intercept) {\n                break;\n              }\n            }\n          }\n          if (!intercept) {\n            shouldKeep = true;\n            break;\n          }\n        }\n      }\n      if (!shouldKeep) {\n        delete collection[anchor];\n      }\n    }\n  }\n\n  intercept(anchorRight);\n  intercept(anchorLeft);\n  intercept(anchorCenter);\n\n  function group(collection: Anchor) {\n    // Sort anchors to process them in order\n    const sortedAnchors = Object.keys(collection)\n      .map((a) => parseFloat(a))\n      .sort((a, b) => a - b);\n\n    // Merge nearby anchors within a tolerance\n    // Use 2 units as tolerance - this catches columns that are close but not exactly aligned\n    const MERGE_TOLERANCE = 2;\n\n    for (let i = 0; i < sortedAnchors.length; i++) {\n      const anchor = sortedAnchors[i];\n      if (!(anchor in collection)) continue; // Already merged\n\n      // Look for nearby anchors to merge into this one or merge this into\n      for (let j = i + 1; j < sortedAnchors.length; j++) {\n        const nextAnchor = sortedAnchors[j];\n        if (!(nextAnchor in collection)) continue;\n\n        // Stop if we're beyond the tolerance\n        if (nextAnchor - anchor > MERGE_TOLERANCE) break;\n\n        // Merge the smaller anchor into the larger one\n        if (collection[nextAnchor].length > collection[anchor].length) {\n          collection[nextAnchor].push(...collection[anchor]);\n          delete collection[anchor];\n          break; // This anchor is gone, move to next\n        } else {\n          collection[anchor].push(...collection[nextAnchor]);\n          delete collection[nextAnchor];\n        }\n      }\n    }\n  }\n\n  function anyAnchorSurvived(bbox: ProjectionTextBox) {\n    return (\n      roundAnchor(bbox.x) in anchorLeft ||\n      roundAnchor(bbox.x + bbox.w) in anchorRight ||\n      Math.round(bbox.x + bbox.w / 2) in anchorCenter\n    );\n  }\n\n  // Try seeing if a floating bbox would align well with a surviving anchor on a line immediately above or below it\n  function tryAlignFloating(\n    collection: Anchor,\n    ANCHOR_MARGIN: number,\n    refXFromBbox: (bbox: ProjectionTextBox) => number,\n    anchorValFromBbox: (bbox: ProjectionTextBox) => number\n  ) {\n    for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\n      const line = lines[lineIndex];\n      for (const bbox of line) {\n        // Only consider floating bboxes\n        if (anyAnchorSurvived(bbox)) {\n          continue;\n        }\n        // Check the lines before and after\n        const candidateLines: ProjectionTextBox[][] = [];\n        if (lineIndex > 0) {\n          candidateLines.push(lines[lineIndex - 1]);\n        }\n        if (lineIndex < lines.length - 1) {\n          candidateLines.push(lines[lineIndex + 1]);\n        }\n\n        // Check candidate lines for:\n        // Possible alignment\n        // Being within the margin\n        // Being the closest of the candidates\n        let candidateAnchor: string = \"\";\n        let prevDiff = ANCHOR_MARGIN + 1;\n        for (const candLine of candidateLines) {\n          for (const candBBox of candLine) {\n            const candAnchorVal = anchorValFromBbox(candBBox);\n            if (!(candAnchorVal in collection)) {\n              continue;\n            }\n            const xDiff = Math.abs(candAnchorVal - refXFromBbox(bbox));\n            if (xDiff <= ANCHOR_MARGIN && xDiff < prevDiff) {\n              candidateAnchor = candAnchorVal.toString();\n              prevDiff = xDiff;\n            }\n          }\n        }\n\n        // No candidate found\n        if (candidateAnchor.length == 0) {\n          continue;\n        }\n\n        // Candidate found - update the anchor's bbox list\n        // But first check if the bbox is already in this anchor (could happen after merging)\n        const targetAnchor = collection[parseFloat(candidateAnchor)];\n        if (!targetAnchor.includes(bbox)) {\n          targetAnchor.push(bbox);\n        }\n      }\n    }\n  }\n\n  // Try to left-align floating bboxes\n  tryAlignFloating(\n    anchorLeft,\n    2,\n    (bbox) => bbox.x,\n    (bbox) => roundAnchor(bbox.x)\n  );\n\n  // Sort the anchors' lists of bboxes by y-value\n  function sortAnchor(collection: Anchor) {\n    for (const anchor in collection) {\n      collection[anchor].sort((a, b) => a.y - b.y);\n    }\n  }\n\n  sortAnchor(anchorLeft);\n  sortAnchor(anchorRight);\n  sortAnchor(anchorCenter);\n\n  // deduplicate\n  const duplicates = [];\n  for (const anchor in anchorLeft) {\n    for (const item of anchorLeft[anchor]) {\n      item.snap = \"left\";\n      item.leftAnchor = anchor;\n    }\n  }\n\n  for (const anchor in anchorRight) {\n    for (const item of anchorRight[anchor]) {\n      if (item.snap) {\n        item.isDup = true;\n        duplicates.push(item);\n      }\n      item.snap = \"right\";\n      item.rightAnchor = anchor;\n    }\n  }\n\n  for (const anchor in anchorCenter) {\n    for (const item of anchorCenter[anchor]) {\n      if (item.snap && !item.isDup) {\n        item.isDup = true;\n        duplicates.push(item);\n      }\n      item.snap = \"center\";\n      item.centerAnchor = anchor;\n    }\n  }\n\n  function anchorCounts(item: ProjectionTextBox): number[] {\n    let leftCount = 0;\n    if (item.leftAnchor) {\n      const key = parseFloat(item.leftAnchor);\n      leftCount = anchorLeft[key] ? anchorLeft[key].length : 0;\n    }\n    let rightCount = 0;\n    if (item.rightAnchor) {\n      const key = parseFloat(item.rightAnchor);\n      rightCount = anchorRight[key] ? anchorRight[key].length : 0;\n    }\n    let centerCount = 0;\n    if (item.centerAnchor) {\n      const key = parseFloat(item.centerAnchor);\n      centerCount = anchorCenter[key] ? anchorCenter[key].length : 0;\n    }\n    return [leftCount, rightCount, centerCount];\n  }\n\n  // find all left aligned blocks, all right aligned blocks, all centered blocks, in that order\n  // we cannot check all 3 at once since we may end up double counting potential anchor matches\n  // (i.e. we need to exclude block that we know are left/right aligned before counting possible\n  // matching centered blocks)\n\n  // find all lefts\n  let hasChanged = true;\n  while (hasChanged && duplicates.length > 0) {\n    hasChanged = false;\n    for (let i = duplicates.length - 1; i >= 0; --i) {\n      const item = duplicates[i];\n      const [leftCount, rightCount, centerCount] = anchorCounts(item);\n      if (leftCount >= rightCount && leftCount >= centerCount) {\n        item.snap = \"left\";\n        if (item.rightAnchor) {\n          const key = parseFloat(item.rightAnchor);\n          if (anchorRight[key]) {\n            const idx = anchorRight[key].indexOf(item);\n            if (idx >= 0) {\n              anchorRight[key].splice(idx, 1);\n              hasChanged = true;\n            }\n          }\n        }\n        if (item.centerAnchor) {\n          const key = parseFloat(item.centerAnchor);\n          if (anchorCenter[key]) {\n            const idx = anchorCenter[key].indexOf(item);\n            if (idx >= 0) {\n              anchorCenter[key].splice(idx, 1);\n              hasChanged = true;\n            }\n          }\n        }\n        duplicates.splice(i, 1);\n      }\n    }\n  }\n\n  // find all rights\n  hasChanged = true;\n  while (hasChanged && duplicates.length > 0) {\n    hasChanged = false;\n    for (let i = duplicates.length - 1; i >= 0; --i) {\n      const item = duplicates[i];\n      const [leftCount, rightCount, centerCount] = anchorCounts(item);\n      if (rightCount >= leftCount && rightCount >= centerCount) {\n        item.snap = \"right\";\n        if (item.leftAnchor) {\n          const key = parseFloat(item.leftAnchor);\n          if (anchorLeft[key]) {\n            const idx = anchorLeft[key].indexOf(item);\n            if (idx >= 0) {\n              anchorLeft[key].splice(idx, 1);\n              hasChanged = true;\n            }\n          }\n        }\n        if (item.centerAnchor) {\n          const key = parseFloat(item.centerAnchor);\n          if (anchorCenter[key]) {\n            const idx = anchorCenter[key].indexOf(item);\n            if (idx >= 0) {\n              anchorCenter[key].splice(idx, 1);\n              hasChanged = true;\n            }\n          }\n        }\n        duplicates.splice(i, 1);\n      }\n    }\n  }\n\n  // remaining duplicates are centered\n  for (const item of duplicates) {\n    item.snap = \"center\";\n    if (item.leftAnchor) {\n      const key = parseFloat(item.leftAnchor);\n      if (anchorLeft[key]) {\n        const idx = anchorLeft[key].indexOf(item);\n        if (idx >= 0) {\n          anchorLeft[key].splice(idx, 1);\n        }\n      }\n    }\n    if (item.rightAnchor) {\n      const key = parseFloat(item.rightAnchor);\n      if (anchorRight[key]) {\n        const idx = anchorRight[key].indexOf(item);\n        if (idx >= 0) {\n          anchorRight[key].splice(idx, 1);\n        }\n      }\n    }\n  }\n\n  // filter anchors\n  // delete singleton\n  for (const anchor in anchorLeft) {\n    if (anchorLeft[anchor].length < 2) {\n      if (anchorLeft[anchor].length) {\n        delete anchorLeft[anchor][0].snap;\n      }\n      delete anchorLeft[anchor];\n    }\n  }\n\n  for (const anchor in anchorRight) {\n    if (anchorRight[anchor].length < 2) {\n      if (anchorRight[anchor].length) {\n        delete anchorRight[anchor][0].snap;\n      }\n      delete anchorRight[anchor];\n    }\n  }\n\n  for (const anchor in anchorCenter) {\n    if (anchorCenter[anchor].length < 2) {\n      if (anchorCenter[anchor].length) {\n        delete anchorCenter[anchor][0].snap;\n      }\n      delete anchorCenter[anchor];\n    }\n  }\n\n  return {\n    anchorLeft,\n    anchorRight,\n    anchorCenter,\n  };\n}\n\nfunction handleRotationReadingOrder(textBbox: ProjectionTextBox[], pageHeight: number) {\n  // if no bbox is rotated (.r is set), return\n  if (!textBbox.find((b) => b.r != 0)) {\n    return;\n  }\n\n  // Group ALL items by rotation value (not by consecutive items)\n  // This ensures rotated text blocks stay together even when their X coordinates\n  // overlap with non-rotated content (e.g., rotated table + footer at same X positions)\n  const groupsByRotation: { [key: number]: ProjectionTextBox[] } = {};\n  for (const bbox of textBbox) {\n    const r = bbox.r || 0;\n    if (!groupsByRotation[r]) {\n      groupsByRotation[r] = [];\n    }\n    groupsByRotation[r].push(bbox);\n  }\n\n  // Build bboxGroup array from rotation groups, sorted by X position of group\n  const bboxGroup: ProjectionTextBox[][] = [];\n  for (const rotation in groupsByRotation) {\n    const group = groupsByRotation[rotation];\n    // Sort each group by Y for proper reading order\n    group.sort((a, b) => a.y - b.y);\n    bboxGroup.push(group);\n  }\n\n  // Sort groups by their minimum X position to maintain left-to-right order\n  bboxGroup.sort((a, b) => {\n    const minXA = Math.min(...a.map((item) => item.x));\n    const minXB = Math.min(...b.map((item) => item.x));\n    return minXA - minXB;\n  });\n\n  // NOTE/ WARNING: height and width of bbox are NOT rotated beforehand!\n  for (const [index, group] of bboxGroup.entries()) {\n    if (group[0].r == 90 || group[0].r == 270) {\n      // Check if there are non-rotated items that actually overlap visually (both X and Y)\n      // with the rotated group. X-only overlap is not sufficient because items could\n      // be in completely different parts of the page (e.g., rotated table + footer).\n      let globalOverlap = false;\n      for (const bbox of textBbox) {\n        if (bbox.r != group[0].r) {\n          const overlap = group.find(\n            (b) =>\n              // Check X overlap\n              b.x >= bbox.x &&\n              b.x <= bbox.x + bbox.w &&\n              // Also check Y overlap - items must actually be near each other vertically\n              b.y < bbox.y + bbox.h &&\n              b.y + b.h > bbox.y &&\n              bbox.r != b.r\n          );\n          if (overlap) {\n            globalOverlap = true;\n          }\n        }\n      }\n\n      if (globalOverlap) {\n        // rotate bbox to be horizontal\n        for (const bbox of group) {\n          if (bbox.d) {\n            bbox.y += bbox.d;\n            bbox.d = 0;\n          }\n          bbox.r = 0;\n          bbox.rotated = true;\n        }\n      } else {\n        // insert the bbox group in the Y axis after previous group and before next group.\n        // move Next group by current group height (width as not rotated yet).\n        const groupMaxX = Math.max(...group.map((v) => v.x + v.w));\n\n        let deltaY = 0;\n        if (index != 0) {\n          const previousGroup = bboxGroup[index - 1];\n          const previousGroupMaxY = Math.max(...previousGroup.map((v) => v.y + v.h));\n          // Use pageHeight offset to guarantee no alignment issues with other groups\n          deltaY = previousGroupMaxY + pageHeight;\n        }\n        // clockwise rotation (90 degrees)\n        // - Text reads top-to-bottom in page space\n        // - Y position in page space -> X position after de-rotation\n        // - X position in page space -> Y position after de-rotation (row)\n        if (group[0].r == 90) {\n          for (const bbox of group) {\n            const newX = Math.round(bbox.y);\n            const newY = bbox.x + deltaY;\n            // Swap width and height since text orientation changes\n            const newW = bbox.h;\n            const newH = bbox.w;\n            bbox.x = newX;\n            bbox.y = newY;\n            bbox.w = newW;\n            bbox.h = newH;\n            bbox.r = 0;\n            bbox.rotated = true;\n          }\n        }\n        // counter clockwize rotation (text reads bottom-to-top)\n        // For 270-degree rotation, text at higher Y positions should be\n        // at lower X positions after de-rotation (left-to-right reading order)\n        if (group[0].r == 270) {\n          // For 270-degree counter-clockwise rotation:\n          // - Text reads bottom-to-top in page space\n          // - Y position in page space -> X position after de-rotation (inverted)\n          // - X position in page space -> Y position after de-rotation (row)\n          // - w and h need to be swapped since they represent visual dimensions\n          // For 270-degree rotation: h is the extent along reading direction (string width)\n          const maxY = Math.max(...group.map((b) => b.y + b.h));\n\n          for (const bbox of group) {\n            // Transform coordinates:\n            // - new_x = distance from right edge of rotated block (inverted Y)\n            //   Use h (string width in original coords) for the extent\n            // - new_y = row position (from original X)\n            const newX = Math.round(maxY - bbox.y - bbox.h);\n            // Use exact X for Y (will be grouped by bboxToLine's Y_SORT_TOLERANCE)\n            const newY = bbox.x + deltaY;\n            // Swap width and height since text orientation changes\n            const newW = bbox.h;\n            const newH = bbox.w;\n            bbox.x = newX;\n            bbox.y = newY;\n            bbox.w = newW;\n            bbox.h = newH;\n            bbox.r = 0;\n            bbox.rotated = true;\n          }\n        }\n\n        // Use pageHeight offset to guarantee no alignment issues\n        const globalDelta = deltaY + groupMaxX + pageHeight;\n\n        for (const [otherGroupIndex, other] of bboxGroup.entries()) {\n          if (otherGroupIndex <= index) {\n            continue;\n          }\n          for (const bbox of other) {\n            if (bbox.r == 90 || bbox.r == 270) {\n              bbox.d = (bbox.d ? bbox.d : 0) + globalDelta;\n              continue;\n            }\n            bbox.y += globalDelta;\n          }\n        }\n      }\n    }\n  }\n\n  textBbox.sort((a, b) => {\n    return a.y - b.y;\n  });\n\n  // Handle 180-degree rotated text (upside down)\n  // Since we already grouped by rotation, we can iterate the existing groups\n  for (const group of bboxGroup) {\n    if (group[0].r == 180) {\n      // Sort by X for proper reading order\n      group.sort((a, b) => a.x - b.x);\n      // Switch upside down\n      for (const bbox of group) {\n        bbox.x = Math.round(bbox.ry ?? bbox.y);\n        bbox.y = bbox.rx ?? bbox.x;\n        bbox.r = 0;\n        bbox.rotated = true;\n      }\n    }\n  }\n}\n\nexport function bboxToLine(\n  textBbox: ProjectionTextBox[],\n  medianWidth: number,\n  medianHeight: number,\n  pageWidth?: number\n): ProjectionTextBox[][] {\n  // Y-tolerance for sorting: items within this threshold are considered same line\n  // This handles:\n  // 1. Floating point precision issues between columns (e.g., 334.7400 vs 334.7399)\n  // 2. Subscripts/superscripts which are typically offset by 3-5 units from their base characters\n  // Using a fraction of medianHeight to scale with document font size.\n  const Y_SORT_TOLERANCE = Math.max(medianHeight * 0.5, 5.0);\n\n  // Note: We keep whitespace items as they may be needed for proper word separation.\n  // The spacing calculation handles gaps between items.\n\n  // For two-column documents, detect and mark margin line numbers\n  // These are short numeric items positioned between columns (near the page midpoint)\n  // They should not be merged with column content\n  if (pageWidth) {\n    const midpoint = pageWidth * 0.5;\n    const marginZoneLeft = midpoint - 5;\n    const marginZoneRight = midpoint + 20;\n    for (const bbox of textBbox) {\n      const bboxCenter = bbox.x + bbox.w / 2;\n      // Check if item is in the margin zone and looks like a line number\n      if (\n        bboxCenter > marginZoneLeft &&\n        bboxCenter < marginZoneRight &&\n        bbox.str.trim().match(/^\\d{1,2}[O]?$/) && // 1-2 digits, possibly with O (OCR error for 0)\n        bbox.w < 15 // Line numbers are narrow\n      ) {\n        // Mark as margin item - will be placed on its own line\n        bbox.isMarginLineNumber = true;\n      }\n    }\n  }\n\n  // sort lines on first y axis then x axis (top - left)\n  // Use Y tolerance so items on same visual line sort by x regardless of tiny y differences\n  textBbox.sort((a, b) => {\n    if (Math.abs(a.y - b.y) < Y_SORT_TOLERANCE) {\n      return a.x - b.x;\n    }\n    return a.y - b.y;\n  });\n\n  function canMergeMarkup(previousBbox: ProjectionTextBox, bbox: ProjectionTextBox): boolean {\n    if (!previousBbox.markup && !bbox.markup) {\n      return true;\n    }\n    if (\n      previousBbox.markup &&\n      bbox.markup &&\n      previousBbox.markup.highlight === bbox.markup.highlight &&\n      previousBbox.markup.underline === bbox.markup.underline &&\n      previousBbox.markup.squiggly === bbox.markup.squiggly &&\n      previousBbox.markup.strikeout === bbox.markup.strikeout\n    ) {\n      return true;\n    }\n    return false;\n  }\n\n  function canMerge(previousBbox: ProjectionTextBox, bbox: ProjectionTextBox): boolean {\n    if (bbox.y == previousBbox.y && bbox.h == previousBbox.h) {\n      // Use raw pageBbox width for sub-pixel accurate gap calculation.\n      // The rounded `.w` field can cause a true −0.02px overlap to appear as +0.12px,\n      // and a −0.86px overlap to appear as −0.72px — both outside the old tolerance.\n      // PDFs sometimes encode a single value (e.g. \"119:12\") as a sequence of adjacent\n      // text runs whose bounding boxes touch or slightly overlap (up to ~1px) due to\n      // character spacing / kerning. We must merge these rather than treat them as\n      // separate tokens.\n      const prevRawWidth = previousBbox.pageBbox?.w ?? previousBbox.w;\n      const xDelta = bbox.x - previousBbox.x - prevRawWidth;\n      if (\n        ((xDelta < 0 && xDelta > -1.0) || (xDelta >= 0 && xDelta < 0.1)) &&\n        canMergeMarkup(previousBbox, bbox)\n      ) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  function mergePageBbox(a: ProjectionTextBox, b: ProjectionTextBox): Coordinates {\n    const aBbox = a.pageBbox || { x: a.x, y: a.y, w: a.w, h: a.h };\n    const bBbox = b.pageBbox || { x: b.x, y: b.y, w: b.w, h: b.h };\n    const left = Math.min(aBbox.x, bBbox.x);\n    const top = Math.min(aBbox.y, bBbox.y);\n    const right = Math.max(aBbox.x + aBbox.w, bBbox.x + bBbox.w);\n    const bottom = Math.max(aBbox.y + aBbox.h, bBbox.y + bBbox.h);\n    return { x: left, y: top, w: right - left, h: bottom - top };\n  }\n\n  // merge Continuous bbox\n  for (let i = 1; i < textBbox.length; i++) {\n    const bbox = textBbox[i];\n    const previousBbox = textBbox[i - 1];\n    if (canMerge(previousBbox, bbox)) {\n      previousBbox.w = bbox.x + bbox.w - previousBbox.x;\n      previousBbox.str += bbox.str;\n      previousBbox.strLength += bbox.strLength;\n      previousBbox.pageBbox = mergePageBbox(previousBbox, bbox);\n      textBbox.splice(i, 1);\n      i--;\n    }\n  }\n\n  // try to find the bounding box that align as line and group them by line\n  const lines: ProjectionTextBox[][] = [];\n  let currentLine: ProjectionTextBox[] = [];\n  let previousBbox = null;\n\n  for (const bbox of textBbox) {\n    if (!previousBbox) {\n      currentLine.push(bbox);\n    }\n    // This is where we define how line are build. to be improved\n    else {\n      const lineMinY = Math.min(...currentLine.map((v) => v.y));\n      const lineMaxY = Math.max(...currentLine.map((v) => v.y + v.h));\n\n      let lineCollide = false;\n      for (const currentLineItemBbox of currentLine) {\n        const overlapLenght =\n          Math.min(currentLineItemBbox.x + currentLineItemBbox.w, bbox.x + bbox.w) -\n          Math.max(currentLineItemBbox.x, bbox.x);\n        // Use a minimum threshold to tolerate small overlaps common in PDFs due to:\n        // - character spacing/kerning\n        // - floating-point precision issues\n        // - adjacent items with slightly overlapping bounding boxes\n        // We want to detect true collisions (same text rendered twice) not adjacent text\n        if (overlapLenght > Math.max(medianWidth / 3, 5)) {\n          lineCollide = true;\n          break;\n        }\n      }\n\n      // Don't merge margin line numbers with regular content\n      const currentLineHasMargin = currentLine.some((b) => b.isMarginLineNumber === true);\n      const bboxIsMargin = bbox.isMarginLineNumber === true;\n      const marginMismatch = currentLineHasMargin !== bboxIsMargin;\n\n      // For rotated text, use Y-tolerance based merging since heights may be inconsistent\n      const yTolerance = bbox.rotated ? Math.max(medianHeight * 2, 20) : 0;\n      const yWithinTolerance = bbox.rotated && Math.abs(bbox.y - lineMinY) < yTolerance;\n\n      if (\n        !lineCollide &&\n        !marginMismatch &&\n        (yWithinTolerance ||\n          (bbox.y + bbox.h * 0.5 >= lineMinY && bbox.y + bbox.h * 0.5 <= lineMaxY) ||\n          (bbox.y >= lineMinY && bbox.y <= lineMaxY))\n      ) {\n        currentLine.push(bbox);\n      } else {\n        if (currentLine.length) {\n          lines.push(currentLine);\n        }\n        currentLine = [bbox];\n      }\n    }\n    previousBbox = bbox;\n  }\n\n  if (currentLine.length) {\n    lines.push(currentLine);\n  }\n\n  // sort each line by x\n  for (const line of lines) {\n    line.sort((a, b) => a.x - b.x);\n  }\n\n  // sort lines by y\n  lines.sort((a, b) => a[0].y - b[0].y);\n\n  // merge 'words'\n  const mergeThreshold = 1;\n\n  // Pattern to detect standalone numeric values (financial table numbers)\n  // Matches: numbers with optional commas, decimal points, dollar signs, percentages, negatives\n  const numericPattern = /^[$]?-?[\\d,]+\\.?\\d*%?$/;\n\n  function looksLikeTableNumber(str: string): boolean {\n    const trimmed = str.trim();\n    // Must be at least 2 chars to be a table number (avoid merging single digits)\n    return trimmed.length >= 2 && numericPattern.test(trimmed);\n  }\n\n  for (const line of lines) {\n    for (let i = 1; i < line.length; ++i) {\n      // merge box in word if:\n      // - same height\n      // - less than 2 in space\n      // if (line[i].h == line[i-1].h) {\n      const currentLine = line[i];\n      const previousLine = line[i - 1];\n      if (canMergeMarkup(previousLine, currentLine)) {\n        // Don't merge adjacent numbers in tables - they're separate columns\n        const bothAreNumbers =\n          looksLikeTableNumber(previousLine.str) && looksLikeTableNumber(currentLine.str);\n\n        // Check gap with BOTH rounded width (used elsewhere) and raw width from pageBbox.\n        // Only merge without space if both agree the gap is small enough. This prevents\n        // rounding artifacts from causing word fusions (e.g., \"of\" + \"our\" → \"ofour\"\n        // when Math.round(w) reduces the gap from 1.34 to 1.0)\n        const roundedGap = currentLine.x - previousLine.x - previousLine.w;\n        const rawGap =\n          currentLine.x - previousLine.x - (previousLine.pageBbox?.w ?? previousLine.w);\n        if (!bothAreNumbers && roundedGap <= mergeThreshold && rawGap <= mergeThreshold) {\n          // if same word but less than .7 of prev line\n          if (currentLine.h != 0 && currentLine.h < previousLine.h * 0.7) {\n            // and not starting with space\n            if (currentLine.str[0] == \" \") {\n              break;\n            }\n            if (currentLine.y > previousLine.y + previousLine.h * 0.2) {\n              currentLine.str = strToSubscriptString(currentLine.str);\n            } else {\n              currentLine.str = strToPostScript(currentLine.str);\n            }\n          }\n          previousLine.w = currentLine.x + currentLine.w - previousLine.x;\n          previousLine.str += currentLine.str;\n          previousLine.strLength += currentLine.strLength;\n          previousLine.pageBbox = mergePageBbox(previousLine, currentLine);\n          line.splice(i, 1);\n          i--;\n        } else if (\n          !bothAreNumbers &&\n          currentLine.x - previousLine.x - previousLine.w < previousLine.w / previousLine.strLength\n        ) {\n          // merge if space between this word and previous is less than average\n          // character width (using previous word font size)\n          // But don't merge adjacent numbers - they're likely table columns\n\n          // Now extend the width\n          previousLine.w = currentLine.x + currentLine.w - previousLine.x;\n\n          // Add space between merged items unless the previous already ends with space\n          if (!previousLine.str.endsWith(\" \")) {\n            previousLine.str += \" \";\n            previousLine.strLength += 1;\n          }\n          previousLine.str += currentLine.str;\n          previousLine.strLength += currentLine.strLength;\n          previousLine.pageBbox = mergePageBbox(previousLine, currentLine);\n          line.splice(i, 1);\n          i--;\n        }\n      }\n      // }\n    }\n  }\n\n  // check if we can merge the lines together\n  for (let i = 1; i < lines.length - 1; i++) {\n    const currentLine = lines[i];\n    const previousLine = lines[i - 1];\n\n    const previousLineMinY = Math.min(...previousLine.map((v) => v.y));\n    const previousLineMaxY = Math.max(...previousLine.map((v) => v.y + v.h));\n    const currentLineMinY = Math.min(...currentLine.map((v) => v.y));\n    const currentLineMaxY = Math.max(...currentLine.map((v) => v.y + v.h));\n\n    // does the 2 line overlap?\n    if (previousLineMaxY > currentLineMinY && previousLineMinY < currentLineMaxY) {\n      // check the bboxes of current line and prevline do not overlap\n      let bboxOverlap = false;\n      for (const bbox of currentLine) {\n        for (const prevBbox of previousLine) {\n          if (bbox.x >= prevBbox.x && bbox.x <= prevBbox.x + prevBbox.w) {\n            bboxOverlap = true;\n            break;\n          }\n          if (prevBbox.x >= bbox.x && prevBbox.x <= bbox.x + bbox.w) {\n            bboxOverlap = true;\n            break;\n          }\n        }\n      }\n\n      // merge if no overlap\n      if (!bboxOverlap) {\n        previousLine.push(...currentLine);\n        previousLine.sort((a, b) => a.x - b.x);\n        lines.splice(i--, 1);\n      }\n    }\n  }\n\n  for (let i = 1; i < lines.length; i++) {\n    const previousLineMetrics = getRepresentativeLineMetrics(lines[i - 1], medianHeight);\n    const currentLineMetrics = getRepresentativeLineMetrics(lines[i], medianHeight);\n    const yDelta = currentLineMetrics.top - previousLineMetrics.bottom;\n    const referenceHeight = Math.max(\n      medianHeight,\n      Math.min(previousLineMetrics.height, currentLineMetrics.height)\n    );\n\n    // Calculate the number of blank lines to insert based on vertical spacing\n    // Use medianHeight as a reference for one line spacing\n    if (yDelta > referenceHeight) {\n      // Calculate how many blank lines should be inserted\n      // Round to nearest integer to get approximate number of lines\n      const numBlankLines = Math.round(yDelta / referenceHeight) - 1;\n      // Cap at a reasonable maximum (e.g., 10 blank lines) to avoid extreme cases\n      const linesToInsert = Math.min(Math.max(numBlankLines, 1), 10);\n\n      // Insert the calculated number of blank lines\n      const blankLines = Array(linesToInsert).fill([]);\n      lines.splice(i, 0, ...blankLines);\n      i += linesToInsert;\n    }\n  }\n  return lines;\n}\n\nfunction canRenderBbox(line: ProjectionTextBox[], bbox: ProjectionTextBox): boolean {\n  for (const item of line) {\n    if (item == bbox) {\n      return true;\n    }\n    if (!item.rendered) {\n      return false;\n    }\n  }\n  return false;\n}\n\nfunction updateForwardAnchorRightBound(\n  snapMap: number[],\n  forwardAnchor: ForwardAnchor,\n  rightBound: number,\n  anchorTarget: number\n): void {\n  // Anything snapped to the right of rightBound should be aligned to anchorTarget line length at minimum\n  // Also update nearby positions (within tolerance) to handle slight position variations between rows\n  const POSITION_TOLERANCE = 2;\n\n  for (let i = snapMap.length - 1; i >= 0; --i) {\n    const anchor = snapMap[i];\n    if (rightBound <= anchor) {\n      if (!forwardAnchor[anchor] || anchorTarget > forwardAnchor[anchor]) {\n        forwardAnchor[anchor] = anchorTarget;\n      }\n      // Also update nearby positions within tolerance\n      for (let j = i - 1; j >= 0; --j) {\n        const nearbyAnchor = snapMap[j];\n        if (anchor - nearbyAnchor > POSITION_TOLERANCE) break;\n        if (!forwardAnchor[nearbyAnchor] || anchorTarget > forwardAnchor[nearbyAnchor]) {\n          forwardAnchor[nearbyAnchor] = anchorTarget;\n        }\n      }\n    } else {\n      return;\n    }\n  }\n}\n\nfunction updateForwardAnchors(\n  bbox: ProjectionTextBox,\n  nextBbox: ProjectionTextBox | null,\n  snapMaps: SnapMaps,\n  forwardAnchors: PageForwardAnchors,\n  lineLength: number\n): void {\n  const rightBound = bbox.x + bbox.w;\n  let targetLength = lineLength;\n  if (nextBbox && (nextBbox.shouldSpace ?? 0) > 0) {\n    targetLength += nextBbox.shouldSpace ?? 0;\n  }\n  updateForwardAnchorRightBound(snapMaps.left, forwardAnchors.left, rightBound, targetLength);\n  updateForwardAnchorRightBound(snapMaps.right, forwardAnchors.right, rightBound, targetLength);\n  // we do not update center anchors since centered text may span between snapped columns\n  updateForwardAnchorRightBound(\n    snapMaps.floating,\n    forwardAnchors.floating,\n    rightBound,\n    targetLength\n  );\n}\n\n/**\n * Compute the maximum gap between adjacent items on a line.\n */\nfunction lineMaxGap(line: ProjectionTextBox[]): number {\n  let maxGap = 0;\n  for (let gi = 1; gi < line.length; gi++) {\n    const gap = line[gi].x - (line[gi - 1].x + line[gi - 1].w);\n    if (gap > maxGap) maxGap = gap;\n  }\n  return maxGap;\n}\n\n/**\n * Render a single line as flowing text: join items with single spaces based on gap size.\n * Sets bbox.rendered = true for each item.\n */\nfunction renderLineAsFlowingText(\n  line: ProjectionTextBox[],\n  minX: number,\n  medianWidth: number\n): string {\n  const indent = Math.min(\n    Math.max(Math.round((line[0].x - minX) / medianWidth), 0),\n    FLOWING_MAX_INDENT\n  );\n  let result = \" \".repeat(indent);\n\n  for (let i = 0; i < line.length; i++) {\n    const bbox = line[i];\n    if (i > 0) {\n      const prevBbox = line[i - 1];\n      const gap = bbox.x - (prevBbox.x + prevBbox.w);\n      const spaceThreshold = Math.max(\n        bbox.h * FLOWING_SPACE_HEIGHT_RATIO,\n        FLOWING_SPACE_MIN_THRESHOLD\n      );\n      if (gap > spaceThreshold && !result.endsWith(\" \")) {\n        result += \" \";\n      }\n    }\n    result += bbox.str;\n    bbox.rendered = true;\n  }\n\n  return result;\n}\n\n/**\n * Classify whether a block of lines is flowing paragraph text or structured/tabular content.\n * Flowing text gets a simpler rendering path that avoids grid projection artifacts.\n */\nfunction isFlowingTextBlock(\n  blockLines: ProjectionTextBox[][],\n  anchorLeft: Anchor,\n  anchorRight: Anchor,\n  anchorCenter: Anchor,\n  pageWidth: number\n): boolean {\n  const leftAnchorCount = Object.keys(anchorLeft).length;\n  const rightAnchorCount = Object.keys(anchorRight).length;\n  const centerAnchorCount = Object.keys(anchorCenter).length;\n\n  // Multiple column anchors indicate structured/tabular content\n  if (leftAnchorCount + rightAnchorCount + centerAnchorCount > FLOWING_MAX_TOTAL_ANCHORS)\n    return false;\n  if (leftAnchorCount > FLOWING_MAX_LEFT_ANCHORS) return false;\n\n  // Count non-empty lines and how many span most of the page width\n  let nonEmptyLines = 0;\n  let wideLines = 0;\n  for (const line of blockLines) {\n    if (line.length === 0) continue;\n    nonEmptyLines++;\n    const lineStart = line[0].x;\n    const lineEnd = line[line.length - 1].x + line[line.length - 1].w;\n    if (lineEnd - lineStart > pageWidth * FLOWING_WIDE_LINE_RATIO) wideLines++;\n  }\n\n  // Need enough lines to confidently classify\n  if (nonEmptyLines < FLOWING_MIN_LINES) return false;\n\n  // Majority of lines should span most of page width for flowing text\n  return wideLines / nonEmptyLines > FLOWING_WIDE_LINE_THRESHOLD;\n}\n\n/**\n * Render a flowing text block by joining items with single spaces.\n * Avoids grid projection artifacts (excessive whitespace, fused words)\n * that occur when applying column-alignment logic to paragraph text.\n */\nfunction renderFlowingBlock(\n  lines: ProjectionTextBox[][],\n  block: LineRange,\n  rawLines: string[],\n  medianWidth: number\n): void {\n  // Find the block's left margin\n  let minX = Infinity;\n  for (let i = block.start; i < block.end; i++) {\n    if (lines[i].length > 0) {\n      minX = Math.min(minX, lines[i][0].x);\n    }\n  }\n  if (minX === Infinity) minX = 0;\n\n  for (let lineIndex = block.start; lineIndex < block.end; lineIndex++) {\n    const line = lines[lineIndex];\n    if (!rawLines[lineIndex]) {\n      rawLines[lineIndex] = \"\";\n    }\n    if (line.length === 0) continue;\n\n    rawLines[lineIndex] = renderLineAsFlowingText(line, minX, medianWidth);\n  }\n}\n\nfunction getMedianTextBoxSize(lines: ProjectionTextBox[]): TextBoxSize {\n  // calculate median textBox width\n  const widthList = [];\n  for (const bbox of lines) {\n    if (bbox.w > 0) {\n      widthList.push(bbox.w / bbox.strLength);\n    }\n  }\n  const medianWidth = widthList.sort((a, b) => a - b)[Math.floor(widthList.length / 2)];\n\n  // calculate median textBox height\n  const heightList = [];\n  for (const bbox of lines) {\n    if (bbox.h > 0) {\n      heightList.push(bbox.h);\n    }\n  }\n  const medianHeight = heightList.sort((a, b) => a - b)[Math.floor(heightList.length / 2)];\n  return { width: medianWidth, height: medianHeight };\n}\n\nexport function projectToGrid(\n  config: LiteParseConfig,\n  page: PageData,\n  projectionBoxes: ProjectionTextBox[],\n  prevAnchors: PrevAnchors,\n  totalPages: number,\n  logger: GridDebugLogger\n): { text: string; prevAnchors: PrevAnchors } {\n  // detect '.' garbage in the lines\n  let dotCount = 0;\n  for (const bbox of projectionBoxes) {\n    // check if bbox.str contains only dots\n    if (bbox.str.match(/^\\.+$/)) {\n      dotCount++;\n    }\n  }\n\n  if (dotCount > 100 && dotCount > projectionBoxes.length * 0.05) {\n    // remove all dots and splice them from lines\n    const newLines = [];\n    for (const bbox of projectionBoxes) {\n      if (bbox.str.match(/^\\.+$/)) {\n        continue;\n      }\n      if (bbox.str.match(/^·+$/)) {\n        continue;\n      }\n      if (bbox.str.match(/^\"+$/)) {\n        continue;\n      }\n      newLines.push(bbox);\n    }\n    projectionBoxes = newLines;\n  }\n\n  // calculate median textBox width/height\n  const pageMedianSizes = getMedianTextBoxSize(projectionBoxes);\n  let medianWidth = pageMedianSizes.width;\n  const medianHeight = pageMedianSizes.height;\n\n  // Save original bboxes (including OCR) for text attribution\n  const attributionBboxes: ProjectionTextBox[] = [];\n  for (const bbox of projectionBoxes as ProjectionTextBox[]) {\n    if (!bbox || !bbox.str || bbox.vgap || bbox.isPlaceholder) {\n      continue;\n    }\n    attributionBboxes.push({\n      str: bbox.str,\n      x: bbox.x,\n      y: bbox.y,\n      w: bbox.w,\n      h: bbox.h,\n      r: bbox.r,\n      strLength: bbox.str.length,\n    });\n  }\n\n  handleRotationReadingOrder(projectionBoxes, page.height);\n  const lines = bboxToLine(projectionBoxes, medianWidth, medianHeight, page.width);\n\n  // Log line composition\n  for (let i = 0; i < lines.length; i++) {\n    logger.logLineComposition(i, lines[i]);\n  }\n\n  // remove unprojectable text and apply markup to final lines\n  for (let i = 0; i < lines.length; ++i) {\n    const line = filterUnprojectableText(config, lines[i]);\n    for (const bbox of line) {\n      // With the way our grid projection currently works, we have to output\n      // tags before raw line projection to avoid breaking the projection alignment.\n      // The tags get replaced with MD as needed in output formatting, this does\n      // result in output text containing the ~~ strikeout markup, but this is\n      // mitigated since we skip markup entirely when we are not outputting markdown\n      if (bbox.str.trim().length != 0 && bbox.markup) {\n        bbox.str = applyMarkupTags(bbox.markup, bbox.str);\n      }\n    }\n    lines[i] = line;\n  }\n\n  const forwardAnchors: PageForwardAnchors = {\n    left: {},\n    right: {},\n    center: {},\n    floating: {},\n  };\n\n  const rawLines: string[] = [];\n  const rawLinesDelta = [];\n\n  const blocks: LineRange[] = [];\n  if (config.preserveLayoutAlignmentAcrossPages && totalPages > 1) {\n    blocks.push({ start: 0, end: lines.length });\n  } else {\n    let emptyCount = 0;\n    let start = -1;\n    for (const [lineIndex, line] of lines.entries()) {\n      if (line.length === 0) {\n        emptyCount++;\n        if (emptyCount > 1) {\n          if (start >= 0) {\n            // ignore completely empty blocks, include the double blank\n            // line at the end of valid blocks\n            blocks.push({ start: start, end: lineIndex + 1 });\n          }\n          start = -1;\n        }\n      } else {\n        emptyCount = 0;\n        if (start < 0) {\n          start = lineIndex;\n        }\n      }\n    }\n    if (start > -1) {\n      blocks.push({ start: start, end: lines.length });\n    }\n  }\n\n  // Log block assignments\n  for (let bi = 0; bi < blocks.length; bi++) {\n    logger.logBlock(bi, blocks[bi].start, blocks[bi].end);\n  }\n\n  for (const block of blocks) {\n    const blockLines = lines.slice(block.start, block.end);\n    const { anchorLeft, anchorRight, anchorCenter } = extractAnchorsPointsFromLines(\n      blockLines,\n      page\n    );\n\n    logger.logAnchors(anchorLeft, anchorRight, anchorCenter);\n\n    // Block-level classification: if entire block is clearly flowing text,\n    // render it simply and skip grid projection\n    if (isFlowingTextBlock(blockLines, anchorLeft, anchorRight, anchorCenter, page.width)) {\n      logger.logFlowingBlock(block.start, block.end);\n      if (!config.preserveLayoutAlignmentAcrossPages) {\n        const sizes = getMedianTextBoxSize(blockLines.flat());\n        medianWidth = sizes.width;\n      }\n      renderFlowingBlock(lines, block, rawLines, medianWidth);\n      for (let li = block.start; li < block.end; li++) {\n        if (rawLines[li]) logger.captureRender(li, 0, rawLines[li], \"flowing\");\n      }\n      continue;\n    }\n\n    logger.logStructuredBlock(block.start, block.end);\n\n    const snapMaps: SnapMaps = {\n      left: [],\n      right: [],\n      center: [],\n      floating: [],\n    };\n\n    const uniqueSnaps = new Set<number>();\n    for (const snap in anchorLeft) {\n      uniqueSnaps.add(parseFloat(snap));\n    }\n    snapMaps.left.push(...uniqueSnaps);\n    uniqueSnaps.clear();\n\n    for (const snap in anchorRight) {\n      uniqueSnaps.add(parseFloat(snap));\n    }\n    snapMaps.right.push(...uniqueSnaps);\n    uniqueSnaps.clear();\n\n    for (const snap in anchorCenter) {\n      uniqueSnaps.add(parseFloat(snap));\n    }\n    snapMaps.center.push(...uniqueSnaps);\n    uniqueSnaps.clear();\n\n    let hasChanged = true;\n    const leftSnap: Snap[] = [];\n    const rightSnap: Snap[] = [];\n    const centerSnap: Snap[] = [];\n\n    if (!config.preserveLayoutAlignmentAcrossPages) {\n      const sizes = getMedianTextBoxSize(lines.slice(block.start, block.end).flat());\n      medianWidth = sizes.width;\n\n      // medianHeight updated but not currently used per-block - reserved for future use\n      void sizes.height;\n    }\n\n    // compute snaps\n    for (let lineIndex = block.start; lineIndex < block.end; ++lineIndex) {\n      const line = lines[lineIndex];\n      const forceUnsnapped = !canSnapLine(config, line);\n      let prevBbox = null;\n\n      for (let boxIndex = 0; boxIndex < line.length; ++boxIndex) {\n        const bbox = line[boxIndex];\n        bbox.forceUnsnapped = forceUnsnapped;\n\n        const spaceThreshold = 2;\n        // should we add a space between the two bbox?\n        // TODO RTL\n        if (prevBbox && bbox.x - (prevBbox.x + prevBbox.w) > spaceThreshold) {\n          const xDelta = bbox.x - (prevBbox.x + prevBbox.w);\n          const prevCharWidth = prevBbox.w / prevBbox.strLength;\n\n          // add a space\n          bbox.shouldSpace = 1;\n\n          if (xDelta > prevCharWidth * 2) {\n            // Check if both items are in the same column based on gap size\n            // If gap is less than 10% of page width, treat as same column\n            // This works for any number of columns\n            const columnGapThreshold = page.width * 0.1;\n            const bothInSameColumn = xDelta < columnGapThreshold;\n\n            // insert column spacing if any of:\n            // - gap is more than an approximate tab (8x average char width)\n            // - previous bbox is right snap\n            // - this bbox is left snap\n            // - both previous and this bbox are snaps\n            // otherwise insert floating spacing\n            if (\n              (!bbox.forceUnsnapped && xDelta > prevCharWidth * 8) ||\n              (bbox.snap && bbox.snap === \"left\") ||\n              (prevBbox.snap && prevBbox.snap === \"right\") ||\n              (bbox.snap && prevBbox.snap)\n            ) {\n              // If both items are in the same column, limit spacing to avoid\n              // preserving justified text gaps from PDFs\n              bbox.shouldSpace = bothInSameColumn ? FLOATING_SPACES : COLUMN_SPACES;\n            } else {\n              // For items in the same column, use minimal spacing\n              bbox.shouldSpace = bothInSameColumn ? 1 : FLOATING_SPACES;\n            }\n          }\n        } else {\n          bbox.shouldSpace = 0;\n        }\n\n        prevBbox = bbox;\n        logger.logSnapAssignment(bbox, lineIndex, boxIndex);\n        if (!bbox.snap) {\n          uniqueSnaps.add(Math.round(bbox.x));\n        } else if (bbox.snap == \"left\") {\n          leftSnap.push({ bbox, lineIndex, boxIndex });\n        } else if (bbox.snap == \"right\") {\n          rightSnap.push({ bbox, lineIndex, boxIndex });\n        } else if (bbox.snap == \"center\") {\n          centerSnap.push({ bbox, lineIndex, boxIndex });\n        }\n      }\n    }\n\n    snapMaps.floating.push(...uniqueSnaps);\n    uniqueSnaps.clear();\n\n    snapMaps.floating.sort((a, b) => a - b);\n    snapMaps.center.sort((a, b) => a - b);\n    snapMaps.right.sort((a, b) => a - b);\n    snapMaps.left.sort((a, b) => a - b);\n\n    // Per-line flowing text detection: pre-render lines that are clearly paragraph text\n    // (spans page width, no large column gaps) with simple single-space joining.\n    // This avoids grid projection artifacts on flowing text within mixed blocks.\n    const flowingLines = new Set<number>();\n    {\n      // Find block's left margin for indent calculation\n      let blockMinX = Infinity;\n      for (let li = block.start; li < block.end; li++) {\n        if (lines[li].length > 0) {\n          blockMinX = Math.min(blockMinX, lines[li][0].x);\n        }\n      }\n      if (blockMinX === Infinity) blockMinX = 0;\n\n      const columnGapThreshold = medianWidth * FLOWING_COLUMN_GAP_MULTIPLIER;\n\n      // Helper to mark and render a line as flowing\n      function markFlowing(lineIndex: number, reason: string): void {\n        const line = lines[lineIndex];\n        if (!rawLines[lineIndex]) {\n          rawLines[lineIndex] = \"\";\n          rawLinesDelta[lineIndex] = 0;\n        }\n        rawLines[lineIndex] = renderLineAsFlowingText(line, blockMinX, medianWidth);\n        flowingLines.add(lineIndex);\n        logger.logFlowingLine(lineIndex, reason);\n        logger.captureRender(lineIndex, 0, rawLines[lineIndex], \"flowing\");\n      }\n\n      // First pass: detect clearly flowing lines (wide, no column gaps, enough items)\n      for (let lineIndex = block.start; lineIndex < block.end; lineIndex++) {\n        const line = lines[lineIndex];\n        if (line.length < FLOWING_MIN_LINE_ITEMS) continue;\n\n        const lineStart = line[0].x;\n        const lineEnd = line[line.length - 1].x + line[line.length - 1].w;\n        const lineSpan = lineEnd - lineStart;\n\n        if (\n          lineSpan > page.width * FLOWING_WIDE_LINE_RATIO &&\n          lineMaxGap(line) < columnGapThreshold\n        ) {\n          markFlowing(lineIndex, \"wide span, no column gaps\");\n        }\n      }\n\n      // Second pass: extend flowing to adjacent continuation lines using\n      // forward + backward sweeps (O(n) instead of iterating until convergence)\n      // Forward sweep: propagate flowing status downward\n      for (let lineIndex = block.start; lineIndex < block.end; lineIndex++) {\n        if (flowingLines.has(lineIndex)) continue;\n        const line = lines[lineIndex];\n        if (line.length === 0) continue;\n        if (flowingLines.has(lineIndex - 1) && lineMaxGap(line) < columnGapThreshold) {\n          markFlowing(lineIndex, `forward propagation from line ${lineIndex - 1}`);\n        }\n      }\n      // Backward sweep: propagate flowing status upward\n      for (let lineIndex = block.end - 1; lineIndex >= block.start; lineIndex--) {\n        if (flowingLines.has(lineIndex)) continue;\n        const line = lines[lineIndex];\n        if (line.length === 0) continue;\n        if (flowingLines.has(lineIndex + 1) && lineMaxGap(line) < columnGapThreshold) {\n          markFlowing(lineIndex, `backward propagation from line ${lineIndex + 1}`);\n        }\n      }\n    }\n\n    while (hasChanged || snapMaps.right.length || snapMaps.left.length || snapMaps.center.length) {\n      hasChanged = false;\n\n      for (let lineIndex = block.start; lineIndex < block.end; ++lineIndex) {\n        const line = lines[lineIndex];\n        if (!rawLines[lineIndex]) {\n          rawLines[lineIndex] = \"\";\n          rawLinesDelta[lineIndex] = 0;\n        }\n\n        for (let boxIndex = 0; boxIndex < line.length; ++boxIndex) {\n          const bbox = line[boxIndex];\n          if (bbox.rendered) {\n            continue;\n          }\n\n          if (!bbox.forceUnsnapped) {\n            if (bbox.snap) {\n              continue;\n            }\n\n            if (\n              (snapMaps.left.length && snapMaps.left[0] < bbox.x) ||\n              (snapMaps.right.length && snapMaps.right[0] < bbox.x) ||\n              (snapMaps.center.length && snapMaps.center[0] < Math.round(bbox.x + bbox.w / 2))\n            ) {\n              continue;\n            }\n          }\n\n          if (!canRenderBbox(line, bbox)) {\n            break;\n          }\n\n          let targetX = Math.min(Math.round(bbox.x / medianWidth), COLUMN_SPACES);\n\n          let lastSnapLeft = 0;\n          for (const key in forwardAnchors.left) {\n            // Use parseFloat to preserve decimal precision from anchor keys\n            if (parseFloat(key) <= bbox.x) {\n              lastSnapLeft = Math.max(lastSnapLeft, forwardAnchors.left[key]);\n            }\n          }\n          const lineMax = Math.max(\n            lastSnapLeft,\n            rawLines[lineIndex].trimEnd().length + (bbox.shouldSpace ?? 0)\n          );\n          if (targetX < lineMax) {\n            targetX = lineMax;\n          }\n\n          if (!bbox.forceUnsnapped) {\n            const floatingAnchor = forwardAnchors.floating[Math.round(bbox.x)];\n            if (floatingAnchor && targetX < floatingAnchor) {\n              // Limit floating anchor adjustment to avoid excessive gaps in justified text\n              // Use a small max gap to prevent large spacing within columns\n              const maxFloatingGap = 4;\n              const adjustedAnchor = Math.min(floatingAnchor, targetX + maxFloatingGap);\n              if (adjustedAnchor > targetX) {\n                targetX = adjustedAnchor;\n              }\n            }\n          }\n\n          rawLines[lineIndex] = rawLines[lineIndex].trimEnd();\n          if (targetX > rawLines[lineIndex].length) {\n            rawLines[lineIndex] += \" \".repeat(targetX - rawLines[lineIndex].length);\n          }\n\n          rawLines[lineIndex] += bbox.str;\n\n          bbox.rendered = true;\n          hasChanged = true;\n          logger.logRender(bbox, lineIndex, targetX, \"floating\");\n          logger.captureRender(lineIndex, targetX, bbox.str, \"floating\");\n\n          let nextBbox: ProjectionTextBox | null = null;\n          if (line.length > boxIndex + 1) {\n            nextBbox = line[boxIndex + 1];\n          }\n          if (!bbox.forceUnsnapped) {\n            updateForwardAnchors(\n              bbox,\n              nextBbox,\n              snapMaps,\n              forwardAnchors,\n              rawLines[lineIndex].length\n            );\n          }\n        }\n      }\n\n      if (\n        snapMaps.left.length &&\n        (!snapMaps.right.length || snapMaps.left[0] <= snapMaps.right[0]) &&\n        (!snapMaps.center.length || snapMaps.left[0] <= snapMaps.center[0])\n      ) {\n        const thisTurnSnap: Snap[] = [];\n        for (const item of leftSnap) {\n          if (\n            item.bbox.leftAnchor &&\n            parseFloat(item.bbox.leftAnchor) == snapMaps.left[0] &&\n            !flowingLines.has(item.lineIndex)\n          ) {\n            thisTurnSnap.push(item);\n          }\n        }\n        hasChanged = true;\n        if (!thisTurnSnap.length) {\n          snapMaps.left.shift();\n          continue;\n        }\n\n        let targetX = Math.min(Math.round(snapMaps.left[0] / medianWidth), COLUMN_SPACES);\n        const lineMax = Math.max(\n          ...thisTurnSnap.map((v) => {\n            let spaceEnd = 0;\n            if (!rawLines[v.lineIndex].endsWith(\" \")) {\n              spaceEnd = v.bbox.shouldSpace ?? 0;\n            }\n            if ((v.bbox.shouldSpace ?? 0) > 1) {\n              const trailingSpaces =\n                rawLines[v.lineIndex].length - rawLines[v.lineIndex].trimEnd().length;\n              if (trailingSpaces < (v.bbox.shouldSpace ?? 0)) {\n                spaceEnd = (v.bbox.shouldSpace ?? 0) - trailingSpaces;\n              }\n            }\n\n            return rawLines[v.lineIndex].length + spaceEnd + 1;\n          })\n        );\n\n        if (targetX < lineMax) {\n          targetX = lineMax;\n        }\n\n        if (\n          forwardAnchors.left[snapMaps.left[0]] &&\n          targetX < forwardAnchors.left[snapMaps.left[0]]\n        ) {\n          targetX = forwardAnchors.left[snapMaps.left[0]];\n        }\n        if (\n          prevAnchors.forwardAnchorLeft[snapMaps.left[0]] &&\n          targetX < prevAnchors.forwardAnchorLeft[snapMaps.left[0]]\n        ) {\n          targetX = prevAnchors.forwardAnchorLeft[snapMaps.left[0]];\n        }\n\n        forwardAnchors.left[snapMaps.left[0]] = targetX;\n        logger.logForwardAnchor(\"left\", snapMaps.left[0], targetX);\n\n        for (const currentLeftSnapBox of thisTurnSnap) {\n          const lineIndex = currentLeftSnapBox.lineIndex;\n          if (flowingLines.has(lineIndex)) continue;\n          if (targetX > rawLines[lineIndex].length) {\n            rawLines[lineIndex] += \" \".repeat(targetX - rawLines[lineIndex].length);\n          }\n          rawLines[lineIndex] += currentLeftSnapBox.bbox.str;\n          currentLeftSnapBox.bbox.rendered = true;\n          logger.logRender(currentLeftSnapBox.bbox, lineIndex, targetX, \"left-snap\");\n          logger.captureRender(lineIndex, targetX, currentLeftSnapBox.bbox.str, \"left\");\n\n          let nextBbox: ProjectionTextBox | null = null;\n          if (lines[lineIndex].length > currentLeftSnapBox.boxIndex + 1) {\n            nextBbox = lines[lineIndex][currentLeftSnapBox.boxIndex + 1];\n          }\n          updateForwardAnchors(\n            currentLeftSnapBox.bbox,\n            nextBbox,\n            snapMaps,\n            forwardAnchors,\n            rawLines[lineIndex].length\n          );\n        }\n\n        for (let index = block.start; index < block.end; ++index) {\n          if (flowingLines.has(index)) continue;\n          const line = rawLines[index];\n          if (line.length < targetX) {\n            rawLines[index] += \" \".repeat(targetX - line.length);\n          }\n        }\n        snapMaps.left.shift();\n      } else if (\n        snapMaps.right.length &&\n        (!snapMaps.left.length || snapMaps.right[0] <= snapMaps.left[0]) &&\n        (!snapMaps.center.length || snapMaps.right[0] <= snapMaps.center[0])\n      ) {\n        const thisTurnSnap: Snap[] = [];\n        hasChanged = true;\n        for (const item of rightSnap) {\n          if (\n            item.bbox.rightAnchor &&\n            parseFloat(item.bbox.rightAnchor) == snapMaps.right[0] &&\n            !flowingLines.has(item.lineIndex)\n          ) {\n            thisTurnSnap.push(item);\n          }\n        }\n\n        if (!thisTurnSnap.length) {\n          snapMaps.right.shift();\n          continue;\n        }\n\n        let targetX = Math.min(Math.round(snapMaps.right[0] / medianWidth), COLUMN_SPACES);\n        const lineMax = Math.max(\n          ...thisTurnSnap.map((v) => {\n            let lastSnapLeft = 0;\n            for (const key in forwardAnchors.left) {\n              if (parseInt(key) <= v.bbox.x) {\n                lastSnapLeft = Math.max(lastSnapLeft, forwardAnchors.left[key]);\n              }\n            }\n            return (\n              Math.max(\n                lastSnapLeft,\n                rawLines[v.lineIndex].trimEnd().length + (v.bbox.shouldSpace ?? 0)\n              ) + v.bbox.strLength\n            );\n          })\n        );\n\n        if (targetX < lineMax) {\n          targetX = lineMax;\n        }\n        if (\n          forwardAnchors.right[snapMaps.right[0]] &&\n          targetX < forwardAnchors.right[snapMaps.right[0]]\n        ) {\n          targetX = forwardAnchors.right[snapMaps.right[0]];\n        }\n        if (\n          prevAnchors.forwardAnchorRight[snapMaps.right[0]] &&\n          targetX < prevAnchors.forwardAnchorRight[snapMaps.right[0]]\n        ) {\n          targetX = prevAnchors.forwardAnchorRight[snapMaps.right[0]];\n        }\n        forwardAnchors.right[snapMaps.right[0]] = targetX;\n        logger.logForwardAnchor(\"right\", snapMaps.right[0], targetX);\n\n        for (const currentRightSnapBox of thisTurnSnap) {\n          const lineIndex = currentRightSnapBox.lineIndex;\n          if (flowingLines.has(lineIndex)) continue;\n          rawLines[lineIndex] = rawLines[lineIndex].trimEnd();\n          if (targetX > rawLines[lineIndex].trimEnd().length + currentRightSnapBox.bbox.strLength) {\n            rawLines[lineIndex] += \" \".repeat(\n              targetX - rawLines[lineIndex].length - currentRightSnapBox.bbox.strLength\n            );\n          }\n          rawLines[lineIndex] += currentRightSnapBox.bbox.str;\n          currentRightSnapBox.bbox.rendered = true;\n          logger.logRender(currentRightSnapBox.bbox, lineIndex, targetX, \"right-snap\");\n          logger.captureRender(\n            lineIndex,\n            targetX - currentRightSnapBox.bbox.strLength,\n            currentRightSnapBox.bbox.str,\n            \"right\"\n          );\n\n          let nextBbox: ProjectionTextBox | null = null;\n          if (lines[lineIndex].length > currentRightSnapBox.boxIndex + 1) {\n            nextBbox = lines[lineIndex][currentRightSnapBox.boxIndex + 1];\n          }\n          updateForwardAnchors(\n            currentRightSnapBox.bbox,\n            nextBbox,\n            snapMaps,\n            forwardAnchors,\n            rawLines[lineIndex].length\n          );\n        }\n        for (let index = block.start; index < block.end; ++index) {\n          if (flowingLines.has(index)) continue;\n          const line = rawLines[index];\n          if (line.length < targetX) {\n            rawLines[index] += \" \".repeat(targetX - line.length);\n          }\n        }\n        snapMaps.right.shift();\n      } else if (\n        snapMaps.center.length &&\n        (!snapMaps.left.length || snapMaps.center[0] <= snapMaps.left[0]) &&\n        (!snapMaps.right.length || snapMaps.center[0] <= snapMaps.right[0])\n      ) {\n        const thisTurnSnap: Snap[] = [];\n        hasChanged = true;\n        for (const item of centerSnap) {\n          if (\n            item.bbox.centerAnchor &&\n            parseFloat(item.bbox.centerAnchor) == snapMaps.center[0] &&\n            !flowingLines.has(item.lineIndex)\n          ) {\n            thisTurnSnap.push(item);\n          }\n        }\n        if (!thisTurnSnap.length) {\n          snapMaps.center.shift();\n          continue;\n        }\n        let targetX = Math.min(Math.round(snapMaps.center[0] / medianWidth), COLUMN_SPACES);\n        const lineMax = Math.max(\n          ...thisTurnSnap.map((v) => {\n            let spaceEnd = 0;\n            if (!rawLines[v.lineIndex].endsWith(\" \")) {\n              spaceEnd = v.bbox.shouldSpace ?? 0;\n            }\n            if ((v.bbox.shouldSpace ?? 0) > 1) {\n              const trailingSpaces =\n                rawLines[v.lineIndex].length - rawLines[v.lineIndex].trimEnd().length;\n              if (trailingSpaces < (v.bbox.shouldSpace ?? 0)) {\n                spaceEnd = (v.bbox.shouldSpace ?? 0) - trailingSpaces;\n              }\n            }\n            return rawLines[v.lineIndex].length + Math.round(v.bbox.strLength / 2) + spaceEnd;\n          })\n        );\n\n        if (targetX < lineMax) {\n          targetX = lineMax;\n        }\n        if (\n          forwardAnchors.center[snapMaps.center[0]] &&\n          targetX < forwardAnchors.center[snapMaps.center[0]]\n        ) {\n          targetX = forwardAnchors.center[snapMaps.center[0]];\n        }\n        if (\n          prevAnchors.forwardAnchorCenter[snapMaps.center[0]] &&\n          targetX < prevAnchors.forwardAnchorCenter[snapMaps.center[0]]\n        ) {\n          targetX = prevAnchors.forwardAnchorCenter[snapMaps.center[0]];\n        }\n        forwardAnchors.center[snapMaps.center[0]] = targetX;\n        logger.logForwardAnchor(\"center\", snapMaps.center[0], targetX);\n        for (const currentCenterSnapBox of thisTurnSnap) {\n          if (flowingLines.has(currentCenterSnapBox.lineIndex)) continue;\n          if (\n            targetX >\n            rawLines[currentCenterSnapBox.lineIndex].length +\n              Math.round(currentCenterSnapBox.bbox.strLength / 2)\n          ) {\n            rawLines[currentCenterSnapBox.lineIndex] += \" \".repeat(\n              targetX -\n                rawLines[currentCenterSnapBox.lineIndex].length -\n                Math.round(currentCenterSnapBox.bbox.strLength / 2)\n            );\n          }\n          rawLines[currentCenterSnapBox.lineIndex] += currentCenterSnapBox.bbox.str;\n          currentCenterSnapBox.bbox.rendered = true;\n          logger.logRender(\n            currentCenterSnapBox.bbox,\n            currentCenterSnapBox.lineIndex,\n            targetX,\n            \"center-snap\"\n          );\n          logger.captureRender(\n            currentCenterSnapBox.lineIndex,\n            targetX - Math.round(currentCenterSnapBox.bbox.strLength / 2),\n            currentCenterSnapBox.bbox.str,\n            \"center\"\n          );\n        }\n        snapMaps.center.shift();\n      }\n    }\n  }\n\n  fixSparseBlocks(blocks, rawLines);\n  logger.captureRawLines(rawLines);\n\n  const text = rawLines.join(\"\\n\");\n  // OSS: Return text instead of mutating page object\n  return {\n    text,\n    prevAnchors: {\n      forwardAnchorLeft: forwardAnchors.left,\n      forwardAnchorRight: forwardAnchors.right,\n      forwardAnchorCenter: forwardAnchors.center,\n    },\n  };\n}\n\nexport async function projectPagesToGrid(\n  pages: PageData[],\n  config: LiteParseConfig\n): Promise<ParsedPage[]> {\n  const logger = createGridDebugLogger(config.debug);\n  const prevAnchors: PrevAnchors = {\n    forwardAnchorLeft: {},\n    forwardAnchorRight: {},\n    forwardAnchorCenter: {},\n  };\n\n  const results: ParsedPage[] = [];\n\n  for (const page of pages) {\n    logger.setPage(page.pageNum, page.width, page.height);\n\n    // Build projection boxes from text items\n    const projectionBoxes = buildBbox(page, config);\n\n    // Project to grid\n    const { text, prevAnchors: newAnchors } = projectToGrid(\n      config,\n      page,\n      projectionBoxes,\n      prevAnchors,\n      pages.length,\n      logger\n    );\n\n    // Update forward anchors if preserving across pages\n    if (config.preserveLayoutAlignmentAcrossPages) {\n      for (const anchor in newAnchors.forwardAnchorLeft) {\n        prevAnchors.forwardAnchorLeft[anchor] = newAnchors.forwardAnchorLeft[anchor];\n      }\n      for (const anchor in newAnchors.forwardAnchorRight) {\n        prevAnchors.forwardAnchorRight[anchor] = newAnchors.forwardAnchorRight[anchor];\n      }\n      for (const anchor in newAnchors.forwardAnchorCenter) {\n        prevAnchors.forwardAnchorCenter[anchor] = newAnchors.forwardAnchorCenter[anchor];\n      }\n    }\n\n    // Build result page\n    results.push({\n      pageNum: page.pageNum,\n      width: page.width,\n      height: page.height,\n      text,\n      textItems: page.textItems,\n      boundingBoxes: [],\n    });\n  }\n\n  // Clean raw text (margin detection, etc)\n  cleanRawText(results, config);\n\n  // Flush debug log and render visualizations\n  if (logger.enabled) {\n    await logger.flush();\n    if (logger.shouldVisualize) {\n      const vizPath = logger.debugConfig.visualizePath ?? \"./debug-output\";\n      const paths = await renderAllVisualizations(logger.visualizerPages, vizPath);\n      for (const p of paths) {\n        process.stderr.write(`[grid-debug] Visualization: ${p}\\n`);\n      }\n    }\n  }\n\n  return results;\n}\n"
  },
  {
    "path": "src/processing/gridVisualizer.ts",
    "content": "import sharp from \"sharp\";\nimport { mkdirSync } from \"fs\";\nimport type { VisualizerPageData, RenderedSegment } from \"./gridDebugLogger.js\";\n\n/** Monospace character metrics in pixels. */\nconst CHAR_WIDTH = 7;\nconst CHAR_HEIGHT = 14;\nconst LINE_HEIGHT = 16;\nconst PADDING = 12;\nconst LEGEND_WIDTH = 140;\nconst LEGEND_HEIGHT = 100;\n\n/** Color scheme for snap types */\nconst COLORS: Record<RenderedSegment[\"snap\"], { bg: string; text: string }> = {\n  left: { bg: \"rgba(59,130,246,0.18)\", text: \"#2563eb\" },\n  right: { bg: \"rgba(239,68,68,0.18)\", text: \"#dc2626\" },\n  center: { bg: \"rgba(34,197,94,0.18)\", text: \"#16a34a\" },\n  floating: { bg: \"rgba(156,163,175,0.15)\", text: \"#4b5563\" },\n  flowing: { bg: \"rgba(234,179,8,0.15)\", text: \"#a16207\" },\n};\n\nfunction escapeXml(s: string): string {\n  return s\n    .replace(/&/g, \"&amp;\")\n    .replace(/</g, \"&lt;\")\n    .replace(/>/g, \"&gt;\")\n    .replace(/\"/g, \"&quot;\")\n    .replace(/'/g, \"&apos;\");\n}\n\n/**\n * Render the projected text output as a monospace grid image.\n *\n * Each character of the output text is rendered at its grid position.\n * Text segments are color-coded by snap type so you can visually compare\n * the projection against the original PDF page screenshot.\n */\nexport async function renderGridVisualization(\n  data: VisualizerPageData,\n  outputPath: string\n): Promise<void> {\n  const { rawLines, segments } = data;\n  if (!rawLines || rawLines.length === 0) return;\n\n  // Trim trailing empty lines\n  let lastNonEmpty = rawLines.length - 1;\n  while (lastNonEmpty >= 0 && rawLines[lastNonEmpty].trimEnd().length === 0) {\n    lastNonEmpty--;\n  }\n  const lines = rawLines.slice(0, lastNonEmpty + 1);\n  if (lines.length === 0) return;\n\n  const maxLineLen = Math.max(0, ...lines.map((l) => (l ?? \"\").length));\n  if (maxLineLen === 0 || !Number.isFinite(maxLineLen)) return;\n\n  // Image dimensions\n  const contentWidth = maxLineLen * CHAR_WIDTH;\n  const contentHeight = lines.length * LINE_HEIGHT;\n  const imgWidth = Math.max(1, contentWidth + PADDING * 2 + LEGEND_WIDTH + PADDING);\n  const imgHeight = Math.max(1, contentHeight + PADDING * 2);\n\n  // Build segment lookup: for each (lineIndex, colRange) → snap type\n  // Sort segments by line then column for efficient lookup\n  const segmentsByLine = new Map<number, RenderedSegment[]>();\n  for (const seg of segments) {\n    if (!segmentsByLine.has(seg.lineIndex)) {\n      segmentsByLine.set(seg.lineIndex, []);\n    }\n    segmentsByLine.get(seg.lineIndex)!.push(seg);\n  }\n\n  const svgParts: string[] = [];\n  svgParts.push(\n    `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${imgWidth}\" height=\"${imgHeight}\" viewBox=\"0 0 ${imgWidth} ${imgHeight}\">`\n  );\n\n  // Draw colored background rectangles for each segment\n  for (const [lineIdx, lineSegments] of segmentsByLine) {\n    if (lineIdx > lastNonEmpty) continue;\n    for (const seg of lineSegments) {\n      const color = COLORS[seg.snap];\n      const x = PADDING + seg.gridCol * CHAR_WIDTH;\n      const y = PADDING + lineIdx * LINE_HEIGHT;\n      const w = seg.text.length * CHAR_WIDTH;\n      svgParts.push(\n        `<rect x=\"${x}\" y=\"${y}\" width=\"${w}\" height=\"${LINE_HEIGHT}\" fill=\"${color.bg}\"/>`\n      );\n    }\n  }\n\n  // Render text line by line using colored spans for segments\n  for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {\n    const line = lines[lineIdx] ?? \"\";\n    if (line.length === 0) continue;\n\n    const y = PADDING + lineIdx * LINE_HEIGHT + CHAR_HEIGHT;\n    const lineSegs = segmentsByLine.get(lineIdx) ?? [];\n\n    if (lineSegs.length === 0) {\n      // No segment data — render as plain gray text\n      svgParts.push(\n        `<text x=\"${PADDING}\" y=\"${y}\" font-family=\"monospace\" font-size=\"12\" fill=\"#6b7280\">${escapeXml(line)}</text>`\n      );\n      continue;\n    }\n\n    // Sort segments by column position\n    lineSegs.sort((a, b) => a.gridCol - b.gridCol);\n\n    // Build colored tspans for each segment, with gaps in default color\n    let col = 0;\n    const textParts: string[] = [];\n    textParts.push(`<text y=\"${y}\" font-family=\"monospace\" font-size=\"12\">`);\n\n    for (const seg of lineSegs) {\n      // Gap before this segment (whitespace or untracked text)\n      if (seg.gridCol > col) {\n        const gapText = line.substring(col, seg.gridCol);\n        if (gapText.length > 0) {\n          textParts.push(\n            `<tspan x=\"${PADDING + col * CHAR_WIDTH}\" fill=\"#9ca3af\">${escapeXml(gapText)}</tspan>`\n          );\n        }\n        col = seg.gridCol;\n      }\n\n      // Render the segment with its snap color\n      const color = COLORS[seg.snap];\n      const segText = line.substring(col, col + seg.text.length);\n      if (segText.length > 0) {\n        textParts.push(\n          `<tspan x=\"${PADDING + col * CHAR_WIDTH}\" fill=\"${color.text}\">${escapeXml(segText)}</tspan>`\n        );\n        col += seg.text.length;\n      }\n    }\n\n    // Trailing text after last segment\n    if (col < line.length) {\n      const trailing = line.substring(col);\n      if (trailing.trimEnd().length > 0) {\n        textParts.push(\n          `<tspan x=\"${PADDING + col * CHAR_WIDTH}\" fill=\"#9ca3af\">${escapeXml(trailing)}</tspan>`\n        );\n      }\n    }\n\n    textParts.push(\"</text>\");\n    svgParts.push(textParts.join(\"\"));\n  }\n\n  // Legend\n  const legendX = contentWidth + PADDING * 2;\n  const legendY = PADDING;\n  svgParts.push(\n    `<rect x=\"${legendX}\" y=\"${legendY}\" width=\"${LEGEND_WIDTH}\" height=\"${LEGEND_HEIGHT}\" fill=\"white\" stroke=\"#d1d5db\" stroke-width=\"1\" rx=\"3\"/>`\n  );\n  const legendItems: Array<{ label: string; snap: RenderedSegment[\"snap\"] }> = [\n    { label: \"Left snap\", snap: \"left\" },\n    { label: \"Right snap\", snap: \"right\" },\n    { label: \"Center snap\", snap: \"center\" },\n    { label: \"Floating\", snap: \"floating\" },\n    { label: \"Flowing text\", snap: \"flowing\" },\n  ];\n  for (let i = 0; i < legendItems.length; i++) {\n    const item = legendItems[i];\n    const ly = legendY + 8 + i * 17;\n    const color = COLORS[item.snap];\n    svgParts.push(\n      `<rect x=\"${legendX + 8}\" y=\"${ly}\" width=\"12\" height=\"12\" fill=\"${color.bg}\" stroke=\"${color.text}\" stroke-width=\"1\"/>`\n    );\n    svgParts.push(\n      `<text x=\"${legendX + 26}\" y=\"${ly + 10}\" font-family=\"sans-serif\" font-size=\"11\" fill=\"#374151\">${item.label}</text>`\n    );\n  }\n\n  svgParts.push(\"</svg>\");\n\n  const svgBuffer = Buffer.from(svgParts.join(\"\\n\"));\n\n  await sharp({\n    create: {\n      width: imgWidth,\n      height: imgHeight,\n      channels: 4,\n      background: { r: 255, g: 255, b: 255, alpha: 1 },\n    },\n  })\n    .composite([{ input: svgBuffer, top: 0, left: 0 }])\n    .png({ compressionLevel: 6 })\n    .toFile(outputPath);\n}\n\n/**\n * Render all captured visualization pages to PNG files.\n */\nexport async function renderAllVisualizations(\n  pages: VisualizerPageData[],\n  outputDir: string\n): Promise<string[]> {\n  mkdirSync(outputDir, { recursive: true });\n\n  const paths: string[] = [];\n  for (const page of pages) {\n    const filePath = `${outputDir}/page-${page.pageNum}-grid.png`;\n    await renderGridVisualization(page, filePath);\n    paths.push(filePath);\n  }\n  return paths;\n}\n"
  },
  {
    "path": "src/processing/markupUtils.test.ts",
    "content": "import { describe, expect, it } from \"vitest\";\nimport { MarkupData } from \"../core/types.js\";\nimport { applyMarkupTags } from \"./markupUtils.js\";\n\nconst text = \"hello\";\n\ndescribe(\"test markupUtils\", () => {\n  it(\"test strikeout\", () => {\n    const data: MarkupData = { strikeout: true };\n    expect(applyMarkupTags(data, text)).toBe(`~~${text}~~`);\n  });\n\n  it(\"test underline\", () => {\n    const data: MarkupData = { underline: true };\n    expect(applyMarkupTags(data, text)).toBe(`__${text}__`);\n  });\n\n  it(\"test squiggly\", () => {\n    const data: MarkupData = { squiggly: true };\n    expect(applyMarkupTags(data, text)).toBe(`__${text}__`);\n  });\n\n  it(\"test highlight\", () => {\n    const data: MarkupData = { highlight: \"yes\" };\n    expect(applyMarkupTags(data, text)).toBe(`==${text}==`);\n  });\n\n  it(\"test none\", () => {\n    const data: MarkupData = {};\n    expect(applyMarkupTags(data, text)).toBe(text);\n  });\n});\n"
  },
  {
    "path": "src/processing/markupUtils.ts",
    "content": "import { MarkupData } from \"../core/types.js\";\n\n/**\n * Apply markup tags to text based on markup data\n * Returns text with inline markup tags that can be converted to other formats later\n */\nexport function applyMarkupTags(markup: MarkupData, text: string): string {\n  let result = text;\n\n  // Apply strikeout (~~text~~)\n  if (markup.strikeout) {\n    result = `~~${result}~~`;\n  }\n\n  // Apply underline (__text__)\n  if (markup.underline) {\n    result = `__${result}__`;\n  }\n\n  // Apply squiggly (wavy underline, use underline for now)\n  if (markup.squiggly) {\n    result = `__${result}__`;\n  }\n\n  // Apply highlight (==text==)\n  if (markup.highlight) {\n    result = `==${result}==`;\n  }\n\n  return result;\n}\n"
  },
  {
    "path": "src/processing/ocrUtils.ts",
    "content": "import { Image, EasyOcrResultLine } from \"../engines/pdf/interface.js\";\n\nexport interface OcrBlock {\n  c: string; // Content/text\n  x: number; // X coordinate in page space\n  rx: number; // Raw X coordinate\n  y: number; // Y coordinate in page space\n  ry: number; // Raw Y coordinate\n  w: number; // Width in page space\n  rw: number; // Raw width\n  h: number; // Height in page space\n  rh: number; // Raw height\n  confidence: string | number;\n  fromOcr: boolean;\n}\n\n/**\n * Parse OCR blocks from image with OCR data\n * Converts OCR bounding boxes from image space to page space\n */\nexport function parseImageOcrBlocks(image: Image): OcrBlock[] {\n  if (!image || !image.ocrRaw?.length) {\n    return [];\n  }\n\n  const blocks: OcrBlock[] = [];\n\n  // Calculate ratio to convert from OCR image coordinates to page coordinates\n  const coords = image.coords || { x: 0, y: 0, w: image.width, h: image.height };\n  const xRatio = image.width / coords.w;\n  const yRatio = image.height / coords.h;\n\n  for (const line of image.ocrRaw) {\n    // line format: [[[x1, y1], [x2, y2], [x3, y3], [x4, y4]], 'text', confidence]\n    const [x1, y1] = line[0][0];\n    const [x2, y2] = line[0][2]; // Use opposite corner for bbox\n    const text = line[1];\n    const confidence = line[2];\n\n    // Convert the bounding box to page space\n    const block: OcrBlock = {\n      c: text,\n      x: x1 / xRatio + coords.x,\n      rx: Math.round(x1 / (image.scaleFactor || 1)),\n      y: y1 / yRatio + coords.y,\n      ry: Math.round(y1 / (image.scaleFactor || 1)),\n      w: Math.abs(x2 - x1) / xRatio,\n      rw: Math.round(Math.abs(x2 - x1) / (image.scaleFactor || 1)),\n      h: Math.abs(y2 - y1) / yRatio,\n      rh: Math.round(Math.abs(y2 - y1) / (image.scaleFactor || 1)),\n      confidence,\n      fromOcr: true,\n    };\n    blocks.push(block);\n  }\n\n  return blocks;\n}\n\n/**\n * Parse EasyOCR stdout result into structured format\n */\nexport function easyOcrResultLinesToList(stdOutResult?: string): EasyOcrResultLine[] {\n  if (!stdOutResult?.length) {\n    return [];\n  }\n\n  const lines = stdOutResult.split(\"\\n\");\n  const blocks: EasyOcrResultLine[] = [];\n\n  for (const line of lines) {\n    if (!line.trim()) {\n      continue;\n    }\n\n    // Parse line format: ([[x1, y1], [x2, y2], [x3, y3], [x4, y4]], 'text', confidence)\n    const ocrMatch = line.match(\n      /\\[\\[(.*?), (.*?)\\], \\[(.*?), (.*?)\\], \\[(.*?), (.*?)\\], \\[(.*?), (.*?)\\]\\], ['\"](.*?)['\"], (.*?)\\)$/\n    );\n\n    if (!ocrMatch) {\n      continue;\n    }\n\n    const x1 = Number(ocrMatch[1]);\n    const y1 = Number(ocrMatch[2]);\n    const x2 = Number(ocrMatch[3]);\n    const y2 = Number(ocrMatch[4]);\n    const x3 = Number(ocrMatch[5]);\n    const y3 = Number(ocrMatch[6]);\n    const x4 = Number(ocrMatch[7]);\n    const y4 = Number(ocrMatch[8]);\n    const text = ocrMatch[9];\n    const confidence = ocrMatch[10];\n\n    blocks.push([\n      [\n        [x1, y1],\n        [x2, y2],\n        [x3, y3],\n        [x4, y4],\n      ],\n      text,\n      confidence,\n    ]);\n  }\n\n  return blocks;\n}\n"
  },
  {
    "path": "src/processing/octUtils.test.ts",
    "content": "import { describe, expect, it } from \"vitest\";\nimport { parseImageOcrBlocks, easyOcrResultLinesToList } from \"./ocrUtils\";\nimport { EasyOcrResultLine, Image } from \"../engines/pdf/interface\";\n\nconst mockImage: Image = {\n  x: 0,\n  y: 0,\n  width: 200,\n  height: 100,\n  scaleFactor: 2,\n  coords: { x: 10, y: 20, w: 100, h: 50 },\n  ocrRaw: [\n    [\n      [\n        [0, 0],\n        [40, 0],\n        [40, 20],\n        [0, 20],\n      ],\n      \"Hello\",\n      0.95,\n    ] as EasyOcrResultLine,\n  ],\n};\n\nconst expectedBlock = {\n  c: \"Hello\",\n  x: 0 / 2 + 10, // = 10\n  rx: Math.round(0 / 2), // = 0\n  y: 0 / 2 + 20, // = 20\n  ry: Math.round(0 / 2), // = 0\n  w: 40 / 2, // = 20\n  rw: Math.round(40 / 2), // = 20\n  h: 20 / 2, // = 10\n  rh: Math.round(20 / 2), // = 10\n  confidence: 0.95,\n  fromOcr: true,\n};\n\nconst mockStdOut = \"([[0, 10], [40, 10], [40, 30], [0, 30]], 'Hello', 0.95)\";\n\nconst expectedResult: EasyOcrResultLine[] = [\n  [\n    [\n      [0, 10],\n      [40, 10],\n      [40, 30],\n      [0, 30],\n    ],\n    \"Hello\",\n    \"0.95\", // note: string, since ocrMatch[10] is not parsed with Number()\n  ] as EasyOcrResultLine,\n];\n\ndescribe(\"test ocrUtils\", () => {\n  it(\"test parseImageOcrBlocks success\", () => {\n    const result = parseImageOcrBlocks(mockImage);\n    expect(result.length).toBe(1);\n    expect(result[0]).toStrictEqual(expectedBlock);\n  });\n\n  it(\"test parseImageOcrBlocks failure\", () => {\n    const imageNoRawOcr = {\n      ...mockImage,\n      ocrRaw: [],\n    };\n    const result = parseImageOcrBlocks(imageNoRawOcr);\n    expect(result.length).toBe(0);\n  });\n\n  it(\"test EasyOcrResultLine success\", () => {\n    const result = easyOcrResultLinesToList(mockStdOut);\n    expect(result).toStrictEqual(expectedResult);\n  });\n\n  it(\"test EasyOcrResultLine success\", () => {\n    const result = easyOcrResultLinesToList(\"\");\n    expect(result.length).toBe(0);\n  });\n});\n"
  },
  {
    "path": "src/processing/searchItems.test.ts",
    "content": "import { describe, expect, it } from \"vitest\";\nimport { searchItems } from \"./searchItems\";\nimport { JsonTextItem } from \"../core/types\";\n\nfunction item(\n  text: string,\n  x: number,\n  y: number,\n  width: number,\n  height = 12,\n  fontSize = 12\n): JsonTextItem {\n  return { text, x, y, width, height, fontSize };\n}\n\ndescribe(\"searchItems\", () => {\n  it(\"matches a phrase within a single item\", () => {\n    const items = [item(\"hello world\", 10, 20, 100)];\n    const results = searchItems(items, { phrase: \"hello world\" });\n    expect(results).toHaveLength(1);\n    expect(results[0].text).toBe(\"hello world\");\n    expect(results[0].x).toBe(10);\n    expect(results[0].width).toBe(100);\n  });\n\n  it(\"matches a phrase spanning multiple items\", () => {\n    const items = [item(\"0°C\", 10, 50, 30), item(\"to\", 45, 50, 15), item(\"70°C\", 65, 50, 35)];\n    const results = searchItems(items, { phrase: \"0°C to 70°C\" });\n    expect(results).toHaveLength(1);\n    expect(results[0].text).toBe(\"0°C to 70°C\");\n    expect(results[0].x).toBe(10);\n    expect(results[0].width).toBe(90); // 65 + 35 - 10\n  });\n\n  it(\"narrows match and does not include unrelated leading items\", () => {\n    const items = [item(\"Operating\", 10, 50, 70), item(\"0°C to 70°C\", 85, 50, 90)];\n    const results = searchItems(items, { phrase: \"0°C to 70°C\" });\n    expect(results).toHaveLength(1);\n    expect(results[0].x).toBe(85);\n    expect(results[0].width).toBe(90);\n  });\n\n  it(\"is case-insensitive by default\", () => {\n    const items = [item(\"Revenue Grew\", 10, 20, 100)];\n    const results = searchItems(items, { phrase: \"revenue grew\" });\n    expect(results).toHaveLength(1);\n    expect(results[0].text).toBe(\"revenue grew\");\n  });\n\n  it(\"respects caseSensitive option\", () => {\n    const items = [item(\"pH Level\", 10, 20, 80)];\n    expect(searchItems(items, { phrase: \"pH\", caseSensitive: true })).toHaveLength(1);\n    expect(searchItems(items, { phrase: \"ph\", caseSensitive: true })).toHaveLength(0);\n    expect(searchItems(items, { phrase: \"PH\", caseSensitive: true })).toHaveLength(0);\n  });\n\n  it(\"returns empty array when no match\", () => {\n    const items = [item(\"hello\", 10, 20, 50)];\n    const results = searchItems(items, { phrase: \"goodbye\" });\n    expect(results).toHaveLength(0);\n  });\n\n  it(\"matches spatially adjacent items without inserting a space\", () => {\n    // \"29-CA-\" and \"261755\" are adjacent (gap=0), so joined as \"29-CA-261755\"\n    // \"Case No.\" and \"29-CA-\" have a word gap (gap=5 > tolerance), so space inserted\n    const items = [\n      item(\"Case No.\", 10, 50, 60),\n      item(\"29-CA-\", 75, 50, 50),\n      item(\"261755\", 125, 50, 50),\n    ];\n    const results = searchItems(items, { phrase: \"Case No. 29-CA-261755\" });\n    expect(results).toHaveLength(1);\n    expect(results[0].text).toBe(\"Case No. 29-CA-261755\");\n  });\n\n  it(\"matches adjacent items with en-dash\", () => {\n    // \"pages 10–\" and \"20\" are adjacent (gap=0)\n    const items = [item(\"pages 10\\u2013\", 10, 50, 60), item(\"20\", 70, 50, 20)];\n    const results = searchItems(items, { phrase: \"pages 10\\u201320\" });\n    expect(results).toHaveLength(1);\n  });\n\n  it(\"narrows correctly past adjacent items\", () => {\n    // \"prefix\" has word gap to \"29-CA-\", \"29-CA-\" is adjacent to \"261755\"\n    const items = [\n      item(\"prefix\", 10, 50, 40),\n      item(\"29-CA-\", 55, 50, 50),\n      item(\"261755\", 105, 50, 50),\n    ];\n    const results = searchItems(items, { phrase: \"29-CA-261755\" });\n    expect(results).toHaveLength(1);\n    expect(results[0].x).toBe(55);\n  });\n\n  it(\"merges bounding boxes vertically for wrapped phrases\", () => {\n    const items = [item(\"temperature\", 10, 50, 80, 12), item(\"range\", 10, 65, 40, 12)];\n    const results = searchItems(items, { phrase: \"temperature range\" });\n    expect(results).toHaveLength(1);\n    expect(results[0].y).toBe(50);\n    expect(results[0].height).toBe(27); // 65 + 12 - 50\n  });\n});\n"
  },
  {
    "path": "src/processing/searchItems.ts",
    "content": "import { JsonTextItem, SearchItemsOptions } from \"../core/types.js\";\n\n/**\n * Search text items for matches, returning synthetic merged items for each match.\n *\n * For phrase searches, consecutive text items are concatenated and searched.\n * When a phrase spans multiple items, the result is a single merged item with\n * combined bounding box and the matched text. Font metadata is taken from the\n * first matched item.\n *\n * @example\n * ```typescript\n * import { LiteParse, searchItems } from \"@llamaindex/liteparse\";\n *\n * const parser = new LiteParse({ outputFormat: \"json\" });\n * const result = await parser.parse(\"report.pdf\");\n *\n * for (const page of result.json.pages) {\n *   const matches = searchItems(page.textItems, { phrase: \"0°C to 70°C\" });\n *   for (const match of matches) {\n *     console.log(`Found \"${match.text}\" at (${match.x}, ${match.y})`);\n *   }\n * }\n * ```\n */\nexport function searchItems(items: JsonTextItem[], options: SearchItemsOptions): JsonTextItem[] {\n  const results: JsonTextItem[] = [];\n  const caseSensitive = options.caseSensitive ?? false;\n  const normalize = caseSensitive ? (s: string) => s : (s: string) => s.toLowerCase();\n  const q = normalize(options.phrase);\n\n  // Pre-compute separator between each pair of adjacent items.\n  // If two items are on the same line and the next item starts where the\n  // previous one ends (spatially adjacent), they are joined without a space.\n  // Otherwise a space is inserted.\n  const seps: string[] = new Array(items.length).fill(\"\");\n  for (let i = 1; i < items.length; i++) {\n    const prev = items[i - 1];\n    const cur = items[i];\n    const fontSize = prev.fontSize ?? cur.fontSize ?? 12;\n    const sameLine = Math.abs(cur.y - prev.y) < fontSize * 0.5;\n    const gap = cur.x - (prev.x + prev.width);\n    seps[i] = sameLine && gap <= fontSize * 0.3 ? \"\" : \" \";\n  }\n\n  let start = 0;\n  while (start < items.length) {\n    let combined = \"\";\n    let found = false;\n    for (let end = start; end < items.length; end++) {\n      if (end > start) combined += seps[end];\n      combined += items[end].text;\n      if (normalize(combined).includes(q)) {\n        // Narrow from the left: drop leading items that aren't part of the match\n        let narrowed = combined;\n        let s = start;\n        while (s < end) {\n          const without = narrowed.slice(items[s].text.length + seps[s + 1].length);\n          if (normalize(without).includes(q)) {\n            narrowed = without;\n            s++;\n          } else {\n            break;\n          }\n        }\n\n        // Merge bounding boxes of the matched items\n        const matched = items.slice(s, end + 1);\n        const x = Math.min(...matched.map((m) => m.x));\n        const y = Math.min(...matched.map((m) => m.y));\n        const x2 = Math.max(...matched.map((m) => m.x + m.width));\n        const y2 = Math.max(...matched.map((m) => m.y + m.height));\n\n        results.push({\n          text: options.phrase,\n          x,\n          y,\n          width: x2 - x,\n          height: y2 - y,\n          fontName: matched[0].fontName,\n          fontSize: matched[0].fontSize,\n        });\n\n        // Advance past the match to avoid duplicates\n        start = end + 1;\n        found = true;\n        break;\n      }\n      // Stop expanding if the combined text is already much longer than the query\n      if (combined.length > q.length * 2) break;\n    }\n    if (!found) start++;\n  }\n\n  return results;\n}\n"
  },
  {
    "path": "src/processing/textUtils.test.ts",
    "content": "import { describe, expect, it } from \"vitest\";\nimport { strToPostScript, strToSubscriptString, cleanOcrTableArtifacts } from \"./textUtils\";\n\ndescribe(\"test processing textUtils\", () => {\n  it(\"test strToSubscriptString full conversion\", () => {\n    const originalStr = \"hello123\";\n    const finalStr = strToSubscriptString(originalStr);\n    expect(finalStr).toBe(\"ₕₑₗₗₒ₁₂₃\");\n  });\n\n  it(\"test strToSubscriptString fail conversion\", () => {\n    const originalStr = \"hello123!\";\n    const finalStr = strToSubscriptString(originalStr);\n    expect(finalStr).toBe(\"hello123!\");\n  });\n\n  it(\"test strToPostScript full conversion\", () => {\n    const originalStr = \"hello123\";\n    const finalStr = strToPostScript(originalStr);\n    expect(finalStr).toBe(\"ʰᵉˡˡᵒ¹²³\");\n  });\n\n  it(\"test strToPostScript fail conversion\", () => {\n    const originalStr = \"hello123!\";\n    const finalStr = strToPostScript(originalStr);\n    expect(finalStr).toBe(\"hello123!\");\n  });\n\n  it(\"test cleanOcrTableArtifacts removes trailing bracket from number\", () => {\n    expect(cleanOcrTableArtifacts(\"44520]\")).toBe(\"44520\");\n    expect(cleanOcrTableArtifacts(\"9,674]\")).toBe(\"9,674\");\n    expect(cleanOcrTableArtifacts(\"0.3|\")).toBe(\"0.3\");\n    expect(cleanOcrTableArtifacts(\"63,790|\")).toBe(\"63,790\");\n  });\n\n  it(\"test cleanOcrTableArtifacts removes leading bracket from number\", () => {\n    expect(cleanOcrTableArtifacts(\"|123\")).toBe(\"123\");\n    expect(cleanOcrTableArtifacts(\"[456\")).toBe(\"456\");\n  });\n\n  it(\"test cleanOcrTableArtifacts preserves brackets in non-numeric text\", () => {\n    expect(cleanOcrTableArtifacts(\"(note)\")).toBe(\"(note)\");\n    expect(cleanOcrTableArtifacts(\"[ref]\")).toBe(\"[ref]\");\n    expect(cleanOcrTableArtifacts(\"hello]\")).toBe(\"hello]\");\n  });\n\n  it(\"test cleanOcrTableArtifacts handles special numeric patterns\", () => {\n    expect(cleanOcrTableArtifacts(\"*-123\")).toBe(\"*-123\");\n    expect(cleanOcrTableArtifacts(\"Z\")).toBe(\"Z\");\n    expect(cleanOcrTableArtifacts(\"N/A\")).toBe(\"N/A\");\n  });\n});\n"
  },
  {
    "path": "src/processing/textUtils.ts",
    "content": "/**\n * Clean common OCR artifacts from table documents.\n * OCR often misreads vertical table border lines as bracket-like characters.\n * This is especially common with numbers adjacent to table cell borders.\n *\n * Examples:\n * - \"44520]\" → \"44,520\" (vertical line misread as ])\n * - \"|123\" → \"123\" (vertical line misread as |)\n * - \"0.3|\" → \"0.3\" (vertical line misread as |)\n */\nexport function cleanOcrTableArtifacts(text: string): string {\n  // Characters commonly misread from vertical table borders\n  // These typically appear at the start or end of cell content\n  const borderArtifacts = /^[|[\\](){}]+|[|[\\](){}]+$/g;\n\n  const cleaned = text.trim();\n\n  // Only clean if the core content looks like a number or short text\n  // This avoids incorrectly stripping brackets from actual content like \"(note)\"\n  const withoutArtifacts = cleaned.replace(borderArtifacts, \"\");\n\n  // If removing artifacts leaves us with something that looks like a number,\n  // statistical value, or percentage, use the cleaned version\n  if (withoutArtifacts.length > 0) {\n    // Check if core content is numeric-ish (numbers, commas, periods, asterisks, percent, minus, plus, Z, N/A)\n    const numericPattern = /^[*+-]?[\\d,.\\s]+[%]?$|^[*]?-?[\\d,.\\s]+$|^[ZN]\\/A$|^[Z-]$/;\n    if (numericPattern.test(withoutArtifacts.trim())) {\n      return withoutArtifacts.trim();\n    }\n  }\n\n  return cleaned;\n}\n\n/**\n * Convert string to subscript unicode characters\n */\nexport function strToSubscriptString(str: string): string {\n  const sub: { [key: string]: string } = {\n    \"0\": \"₀\",\n    \"1\": \"₁\",\n    \"2\": \"₂\",\n    \"3\": \"₃\",\n    \"4\": \"₄\",\n    \"5\": \"₅\",\n    \"6\": \"₆\",\n    \"7\": \"₇\",\n    \"8\": \"₈\",\n    \"9\": \"₉\",\n    \"+\": \"₊\",\n    \"-\": \"₋\",\n    a: \"ₐ\",\n    e: \"ₑ\",\n    o: \"ₒ\",\n    x: \"ₓ\",\n    ə: \"ₔ\",\n    h: \"ₕ\",\n    k: \"ₖ\",\n    l: \"ₗ\",\n    m: \"ₘ\",\n    n: \"ₙ\",\n    p: \"ₚ\",\n    r: \"ᵣ\",\n    s: \"ₛ\",\n    t: \"ₜ\",\n  };\n\n  let subStr = \"\";\n  for (let i = 0; i < str.length; i++) {\n    if (!sub[str[i]]) {\n      return str;\n    }\n    subStr += sub[str[i]];\n  }\n\n  return subStr;\n}\n\n/**\n * Convert string to superscript unicode characters\n */\nexport function strToPostScript(str: string): string {\n  const post: { [key: string]: string } = {\n    \"0\": \"⁰\",\n    \"1\": \"¹\",\n    \"2\": \"²\",\n    \"3\": \"³\",\n    \"4\": \"⁴\",\n    \"5\": \"⁵\",\n    \"6\": \"⁶\",\n    \"7\": \"⁷\",\n    \"8\": \"⁸\",\n    \"9\": \"⁹\",\n    \"+\": \"⁺\",\n    \"-\": \"⁻\",\n    a: \"ᵃ\",\n    b: \"ᵇ\",\n    c: \"ᶜ\",\n    d: \"ᵈ\",\n    e: \"ᵉ\",\n    f: \"ᶠ\",\n    g: \"ᵍ\",\n    h: \"ʰ\",\n    i: \"ⁱ\",\n    j: \"ʲ\",\n    k: \"ᵏ\",\n    l: \"ˡ\",\n    m: \"ᵐ\",\n    n: \"ⁿ\",\n    o: \"ᵒ\",\n    p: \"ᵖ\",\n    r: \"ʳ\",\n    s: \"ˢ\",\n    t: \"ᵗ\",\n    u: \"ᵘ\",\n    v: \"ᵛ\",\n    w: \"ʷ\",\n    x: \"ˣ\",\n    y: \"ʸ\",\n    z: \"ᶻ\",\n    A: \"ᴬ\",\n    B: \"ᴮ\",\n    D: \"ᴰ\",\n    E: \"ᴱ\",\n    G: \"ᴳ\",\n    H: \"ᴴ\",\n    I: \"ᴵ\",\n    J: \"ᴶ\",\n    K: \"ᴷ\",\n    L: \"ᴸ\",\n    M: \"ᴹ\",\n    N: \"ᴺ\",\n    O: \"ᴼ\",\n    P: \"ᴾ\",\n    R: \"ᴿ\",\n    T: \"ᵀ\",\n    U: \"ᵁ\",\n    V: \"ⱽ\",\n    W: \"ᵂ\",\n  };\n\n  let postStr = \"\";\n  for (let i = 0; i < str.length; i++) {\n    if (!post[str[i]]) {\n      return str;\n    }\n    postStr += post[str[i]];\n  }\n\n  return postStr;\n}\n"
  },
  {
    "path": "src/vendor/pdfjs/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n"
  },
  {
    "path": "src/vendor/pdfjs/README.md",
    "content": ""
  },
  {
    "path": "src/vendor/pdfjs/cmaps/CNS2-V.bcmap",
    "content": "\u0003RCopyright 1990-2009 Adobe Systems Incorporated.\nAll rights reserved.\nSee ./LICENSE\u0006CNS2-H"
  },
  {
    "path": "src/vendor/pdfjs/cmaps/ETenms-B5-H.bcmap",
    "content": "\u0002RCopyright 1990-2009 Adobe Systems Incorporated.\nAll rights reserved.\nSee ./LICENSE\tETen-B5-H`\u0001 ^\u0001"
  },
  {
    "path": "src/vendor/pdfjs/cmaps/GB-H.bcmap",
    "content": "\u0002RCopyright 1990-2009 Adobe Systems Incorporated.\nAll rights reserved.\nSee ./LICENSE\u0001\u0001!!]aX!!]`21>\u0002\tp\u0002\u000bz$]\u0006\"Rd-U7*\u0017\r\b4%+ Z\u000f {/\u001f\u001c\u0004%<9Kb1].\"\u001f\f`],\"]\n\"]h\"]F\"]$\"]\u0002\"]`\"]>\"]\u001c\"]z\"]X\"]6\"]\u0014\"]r\"]P\"].\"]\f\"]j\"]H\"]&\"]\u0004\"]b\"]@\"]\u001e\"]|\"]Z\"]8\"]\u0016\"]t\"]R\"]0\"]\u000e\"]l\"]J\"](\"]\u0006\"]d\"]B\"] \"X~']W\"]5\"]\u0013\"]q\"]O\"]-\"]\u000b\"]i\"]G\"]%\"]\u0003\"]a\"]?\"]\u001d\"]{\"]Y\"]7\"]\u0015\"]s\"]Q\"]/\"]\r\"]k\"]I\"]'\"]\u0005\"]c\"]A\"]\u001f\"]}\"][\"]9"
  },
  {
    "path": "src/vendor/pdfjs/cmaps/LICENSE",
    "content": "%%Copyright: -----------------------------------------------------------\n%%Copyright: Copyright 1990-2009 Adobe Systems Incorporated.\n%%Copyright: All rights reserved.\n%%Copyright:\n%%Copyright: Redistribution and use in source and binary forms, with or\n%%Copyright: without modification, are permitted provided that the\n%%Copyright: following conditions are met:\n%%Copyright:\n%%Copyright: Redistributions of source code must retain the above\n%%Copyright: copyright notice, this list of conditions and the following\n%%Copyright: disclaimer.\n%%Copyright:\n%%Copyright: Redistributions in binary form must reproduce the above\n%%Copyright: copyright notice, this list of conditions and the following\n%%Copyright: disclaimer in the documentation and/or other materials\n%%Copyright: provided with the distribution. \n%%Copyright:\n%%Copyright: Neither the name of Adobe Systems Incorporated nor the names\n%%Copyright: of its contributors may be used to endorse or promote\n%%Copyright: products derived from this software without specific prior\n%%Copyright: written permission. \n%%Copyright:\n%%Copyright: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n%%Copyright: CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n%%Copyright: INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n%%Copyright: MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n%%Copyright: DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR\n%%Copyright: CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n%%Copyright: SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n%%Copyright: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n%%Copyright: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n%%Copyright: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n%%Copyright: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n%%Copyright: OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n%%Copyright: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n%%Copyright: -----------------------------------------------------------\n"
  },
  {
    "path": "src/vendor/pdfjs/pdf.mjs",
    "content": "/**\n * @licstart The following is the entire license notice for the\n * JavaScript code in this page\n *\n * Copyright 2023 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @licend The above is the entire license notice for the\n * JavaScript code in this page\n */\n\n/******/ var __webpack_modules__ = ({\n\n/***/ 10:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   FontFaceObject: () => (/* binding */ FontFaceObject),\n/* harmony export */   FontLoader: () => (/* binding */ FontLoader)\n/* harmony export */ });\n/* harmony import */ var _shared_util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(292);\n\nclass FontLoader {\n  #systemFonts = new Set();\n  constructor({\n    ownerDocument = globalThis.document,\n    styleElement = null\n  }) {\n    this._document = ownerDocument;\n    this.nativeFontFaces = new Set();\n    this.styleElement = null;\n    this.loadingRequests = [];\n    this.loadTestFontId = 0;\n  }\n  addNativeFontFace(nativeFontFace) {\n    this.nativeFontFaces.add(nativeFontFace);\n    this._document.fonts.add(nativeFontFace);\n  }\n  removeNativeFontFace(nativeFontFace) {\n    this.nativeFontFaces.delete(nativeFontFace);\n    this._document.fonts.delete(nativeFontFace);\n  }\n  insertRule(rule) {\n    if (!this.styleElement) {\n      this.styleElement = this._document.createElement(\"style\");\n      this._document.documentElement.getElementsByTagName(\"head\")[0].append(this.styleElement);\n    }\n    const styleSheet = this.styleElement.sheet;\n    styleSheet.insertRule(rule, styleSheet.cssRules.length);\n  }\n  clear() {\n    for (const nativeFontFace of this.nativeFontFaces) {\n      this._document.fonts.delete(nativeFontFace);\n    }\n    this.nativeFontFaces.clear();\n    this.#systemFonts.clear();\n    if (this.styleElement) {\n      this.styleElement.remove();\n      this.styleElement = null;\n    }\n  }\n  async loadSystemFont({\n    systemFontInfo: info,\n    _inspectFont\n  }) {\n    if (!info || this.#systemFonts.has(info.loadedName)) {\n      return;\n    }\n    (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.assert)(!this.disableFontFace, \"loadSystemFont shouldn't be called when `disableFontFace` is set.\");\n    if (this.isFontLoadingAPISupported) {\n      const {\n        loadedName,\n        src,\n        style\n      } = info;\n      const fontFace = new FontFace(loadedName, src, style);\n      this.addNativeFontFace(fontFace);\n      try {\n        await fontFace.load();\n        this.#systemFonts.add(loadedName);\n        _inspectFont?.(info);\n      } catch {\n        (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(`Cannot load system font: ${info.baseFontName}, installing it could help to improve PDF rendering.`);\n        this.removeNativeFontFace(fontFace);\n      }\n      return;\n    }\n    (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.unreachable)(\"Not implemented: loadSystemFont without the Font Loading API.\");\n  }\n  async bind(font) {\n    if (font.attached || font.missingFile && !font.systemFontInfo) {\n      return;\n    }\n    font.attached = true;\n    if (font.systemFontInfo) {\n      await this.loadSystemFont(font);\n      return;\n    }\n    if (this.isFontLoadingAPISupported) {\n      const nativeFontFace = font.createNativeFontFace();\n      if (nativeFontFace) {\n        this.addNativeFontFace(nativeFontFace);\n        try {\n          await nativeFontFace.loaded;\n        } catch (ex) {\n          (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(`Failed to load font '${nativeFontFace.family}': '${ex}'.`);\n          font.disableFontFace = true;\n          throw ex;\n        }\n      }\n      return;\n    }\n    const rule = font.createFontFaceRule();\n    if (rule) {\n      this.insertRule(rule);\n      if (this.isSyncFontLoadingSupported) {\n        return;\n      }\n      await new Promise(resolve => {\n        const request = this._queueLoadingCallback(resolve);\n        this._prepareFontLoadEvent(font, request);\n      });\n    }\n  }\n  get isFontLoadingAPISupported() {\n    const hasFonts = !!this._document?.fonts;\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, \"isFontLoadingAPISupported\", hasFonts);\n  }\n  get isSyncFontLoadingSupported() {\n    let supported = false;\n    if (_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.isNodeJS) {\n      supported = true;\n    } else if (typeof navigator !== \"undefined\" && typeof navigator?.userAgent === \"string\" && /Mozilla\\/5.0.*?rv:\\d+.*? Gecko/.test(navigator.userAgent)) {\n      supported = true;\n    }\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, \"isSyncFontLoadingSupported\", supported);\n  }\n  _queueLoadingCallback(callback) {\n    function completeRequest() {\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.assert)(!request.done, \"completeRequest() cannot be called twice.\");\n      request.done = true;\n      while (loadingRequests.length > 0 && loadingRequests[0].done) {\n        const otherRequest = loadingRequests.shift();\n        setTimeout(otherRequest.callback, 0);\n      }\n    }\n    const {\n      loadingRequests\n    } = this;\n    const request = {\n      done: false,\n      complete: completeRequest,\n      callback\n    };\n    loadingRequests.push(request);\n    return request;\n  }\n  get _loadTestFont() {\n    const testFont = atob(\"T1RUTwALAIAAAwAwQ0ZGIDHtZg4AAAOYAAAAgUZGVE1lkzZwAAAEHAAAABxHREVGABQA\" + \"FQAABDgAAAAeT1MvMlYNYwkAAAEgAAAAYGNtYXABDQLUAAACNAAAAUJoZWFk/xVFDQAA\" + \"ALwAAAA2aGhlYQdkA+oAAAD0AAAAJGhtdHgD6AAAAAAEWAAAAAZtYXhwAAJQAAAAARgA\" + \"AAAGbmFtZVjmdH4AAAGAAAAAsXBvc3T/hgAzAAADeAAAACAAAQAAAAEAALZRFsRfDzz1\" + \"AAsD6AAAAADOBOTLAAAAAM4KHDwAAAAAA+gDIQAAAAgAAgAAAAAAAAABAAADIQAAAFoD\" + \"6AAAAAAD6AABAAAAAAAAAAAAAAAAAAAAAQAAUAAAAgAAAAQD6AH0AAUAAAKKArwAAACM\" + \"AooCvAAAAeAAMQECAAACAAYJAAAAAAAAAAAAAQAAAAAAAAAAAAAAAFBmRWQAwAAuAC4D\" + \"IP84AFoDIQAAAAAAAQAAAAAAAAAAACAAIAABAAAADgCuAAEAAAAAAAAAAQAAAAEAAAAA\" + \"AAEAAQAAAAEAAAAAAAIAAQAAAAEAAAAAAAMAAQAAAAEAAAAAAAQAAQAAAAEAAAAAAAUA\" + \"AQAAAAEAAAAAAAYAAQAAAAMAAQQJAAAAAgABAAMAAQQJAAEAAgABAAMAAQQJAAIAAgAB\" + \"AAMAAQQJAAMAAgABAAMAAQQJAAQAAgABAAMAAQQJAAUAAgABAAMAAQQJAAYAAgABWABY\" + \"AAAAAAAAAwAAAAMAAAAcAAEAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAAAC7//wAA\" + \"AC7////TAAEAAAAAAAABBgAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\" + \"AAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\" + \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\" + \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\" + \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\" + \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAD/gwAyAAAAAQAAAAAAAAAAAAAAAAAA\" + \"AAABAAQEAAEBAQJYAAEBASH4DwD4GwHEAvgcA/gXBIwMAYuL+nz5tQXkD5j3CBLnEQAC\" + \"AQEBIVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYAAABAQAADwACAQEEE/t3\" + \"Dov6fAH6fAT+fPp8+nwHDosMCvm1Cvm1DAz6fBQAAAAAAAABAAAAAMmJbzEAAAAAzgTj\" + \"FQAAAADOBOQpAAEAAAAAAAAADAAUAAQAAAABAAAAAgABAAAAAAAAAAAD6AAAAAAAAA==\");\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, \"_loadTestFont\", testFont);\n  }\n  _prepareFontLoadEvent(font, request) {\n    function int32(data, offset) {\n      return data.charCodeAt(offset) << 24 | data.charCodeAt(offset + 1) << 16 | data.charCodeAt(offset + 2) << 8 | data.charCodeAt(offset + 3) & 0xff;\n    }\n    function spliceString(s, offset, remove, insert) {\n      const chunk1 = s.substring(0, offset);\n      const chunk2 = s.substring(offset + remove);\n      return chunk1 + insert + chunk2;\n    }\n    let i, ii;\n    const canvas = this._document.createElement(\"canvas\");\n    canvas.width = 1;\n    canvas.height = 1;\n    const ctx = canvas.getContext(\"2d\");\n    let called = 0;\n    function isFontReady(name, callback) {\n      if (++called > 30) {\n        (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(\"Load test font never loaded.\");\n        callback();\n        return;\n      }\n      ctx.font = \"30px \" + name;\n      ctx.fillText(\".\", 0, 20);\n      const imageData = ctx.getImageData(0, 0, 1, 1);\n      if (imageData.data[3] > 0) {\n        callback();\n        return;\n      }\n      setTimeout(isFontReady.bind(null, name, callback));\n    }\n    const loadTestFontId = `lt${Date.now()}${this.loadTestFontId++}`;\n    let data = this._loadTestFont;\n    const COMMENT_OFFSET = 976;\n    data = spliceString(data, COMMENT_OFFSET, loadTestFontId.length, loadTestFontId);\n    const CFF_CHECKSUM_OFFSET = 16;\n    const XXXX_VALUE = 0x58585858;\n    let checksum = int32(data, CFF_CHECKSUM_OFFSET);\n    for (i = 0, ii = loadTestFontId.length - 3; i < ii; i += 4) {\n      checksum = checksum - XXXX_VALUE + int32(loadTestFontId, i) | 0;\n    }\n    if (i < loadTestFontId.length) {\n      checksum = checksum - XXXX_VALUE + int32(loadTestFontId + \"XXX\", i) | 0;\n    }\n    data = spliceString(data, CFF_CHECKSUM_OFFSET, 4, (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.string32)(checksum));\n    const url = `url(data:font/opentype;base64,${btoa(data)});`;\n    const rule = `@font-face {font-family:\"${loadTestFontId}\";src:${url}}`;\n    this.insertRule(rule);\n    const div = this._document.createElement(\"div\");\n    div.style.visibility = \"hidden\";\n    div.style.width = div.style.height = \"10px\";\n    div.style.position = \"absolute\";\n    div.style.top = div.style.left = \"0px\";\n    for (const name of [font.loadedName, loadTestFontId]) {\n      const span = this._document.createElement(\"span\");\n      span.textContent = \"Hi\";\n      span.style.fontFamily = name;\n      div.append(span);\n    }\n    this._document.body.append(div);\n    isFontReady(loadTestFontId, () => {\n      div.remove();\n      request.complete();\n    });\n  }\n}\nclass FontFaceObject {\n  constructor(translatedData, {\n    isEvalSupported = true,\n    disableFontFace = false,\n    ignoreErrors = false,\n    inspectFont = null\n  }) {\n    this.compiledGlyphs = Object.create(null);\n    for (const i in translatedData) {\n      this[i] = translatedData[i];\n    }\n    this.isEvalSupported = isEvalSupported !== false;\n    this.disableFontFace = disableFontFace === true;\n    this.ignoreErrors = ignoreErrors === true;\n    this._inspectFont = inspectFont;\n  }\n  createNativeFontFace() {\n    if (!this.data || this.disableFontFace) {\n      return null;\n    }\n    let nativeFontFace;\n    if (!this.cssFontInfo) {\n      nativeFontFace = new FontFace(this.loadedName, this.data, {});\n    } else {\n      const css = {\n        weight: this.cssFontInfo.fontWeight\n      };\n      if (this.cssFontInfo.italicAngle) {\n        css.style = `oblique ${this.cssFontInfo.italicAngle}deg`;\n      }\n      nativeFontFace = new FontFace(this.cssFontInfo.fontFamily, this.data, css);\n    }\n    this._inspectFont?.(this);\n    return nativeFontFace;\n  }\n  createFontFaceRule() {\n    if (!this.data || this.disableFontFace) {\n      return null;\n    }\n    const data = (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.bytesToString)(this.data);\n    const url = `url(data:${this.mimetype};base64,${btoa(data)});`;\n    let rule;\n    if (!this.cssFontInfo) {\n      rule = `@font-face {font-family:\"${this.loadedName}\";src:${url}}`;\n    } else {\n      let css = `font-weight: ${this.cssFontInfo.fontWeight};`;\n      if (this.cssFontInfo.italicAngle) {\n        css += `font-style: oblique ${this.cssFontInfo.italicAngle}deg;`;\n      }\n      rule = `@font-face {font-family:\"${this.cssFontInfo.fontFamily}\";${css}src:${url}}`;\n    }\n    this._inspectFont?.(this, url);\n    return rule;\n  }\n  getPathGenerator(objs, character) {\n    if (this.compiledGlyphs[character] !== undefined) {\n      return this.compiledGlyphs[character];\n    }\n    let cmds;\n    try {\n      cmds = objs.get(this.loadedName + \"_path_\" + character);\n    } catch (ex) {\n      if (!this.ignoreErrors) {\n        throw ex;\n      }\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(`getPathGenerator - ignoring character: \"${ex}\".`);\n      return this.compiledGlyphs[character] = function (c, size) {};\n    }\n    if (this.isEvalSupported && _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.FeatureTest.isEvalSupported) {\n      const jsBuf = [];\n      for (const current of cmds) {\n        const args = current.args !== undefined ? current.args.join(\",\") : \"\";\n        jsBuf.push(\"c.\", current.cmd, \"(\", args, \");\\n\");\n      }\n      return this.compiledGlyphs[character] = new Function(\"c\", \"size\", jsBuf.join(\"\"));\n    }\n    return this.compiledGlyphs[character] = function (c, size) {\n      for (const current of cmds) {\n        if (current.cmd === \"scale\") {\n          current.args = [size, -size];\n        }\n        c[current.cmd].apply(c, current.args);\n      }\n    };\n  }\n}\n\n\n/***/ }),\n\n/***/ 47:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   DrawLayer: () => (/* binding */ DrawLayer)\n/* harmony export */ });\n/* harmony import */ var _display_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(419);\n/* harmony import */ var _shared_util_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(292);\n\n\nclass DrawLayer {\n  #parent = null;\n  #id = 0;\n  #mapping = new Map();\n  #toUpdate = new Map();\n  constructor({\n    pageIndex\n  }) {\n    this.pageIndex = pageIndex;\n  }\n  setParent(parent) {\n    if (!this.#parent) {\n      this.#parent = parent;\n      return;\n    }\n    if (this.#parent !== parent) {\n      if (this.#mapping.size > 0) {\n        for (const root of this.#mapping.values()) {\n          root.remove();\n          parent.append(root);\n        }\n      }\n      this.#parent = parent;\n    }\n  }\n  static get _svgFactory() {\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, \"_svgFactory\", new _display_utils_js__WEBPACK_IMPORTED_MODULE_0__.DOMSVGFactory());\n  }\n  static #setBox(element, {\n    x = 0,\n    y = 0,\n    width = 1,\n    height = 1\n  } = {}) {\n    const {\n      style\n    } = element;\n    style.top = `${100 * y}%`;\n    style.left = `${100 * x}%`;\n    style.width = `${100 * width}%`;\n    style.height = `${100 * height}%`;\n  }\n  #createSVG(box) {\n    const svg = DrawLayer._svgFactory.create(1, 1, true);\n    this.#parent.append(svg);\n    svg.setAttribute(\"aria-hidden\", true);\n    DrawLayer.#setBox(svg, box);\n    return svg;\n  }\n  #createClipPath(defs, pathId) {\n    const clipPath = DrawLayer._svgFactory.createElement(\"clipPath\");\n    defs.append(clipPath);\n    const clipPathId = `clip_${pathId}`;\n    clipPath.setAttribute(\"id\", clipPathId);\n    clipPath.setAttribute(\"clipPathUnits\", \"objectBoundingBox\");\n    const clipPathUse = DrawLayer._svgFactory.createElement(\"use\");\n    clipPath.append(clipPathUse);\n    clipPathUse.setAttribute(\"href\", `#${pathId}`);\n    clipPathUse.classList.add(\"clip\");\n    return clipPathId;\n  }\n  highlight(outlines, color, opacity, isPathUpdatable = false) {\n    const id = this.#id++;\n    const root = this.#createSVG(outlines.box);\n    root.classList.add(\"highlight\");\n    if (outlines.free) {\n      root.classList.add(\"free\");\n    }\n    const defs = DrawLayer._svgFactory.createElement(\"defs\");\n    root.append(defs);\n    const path = DrawLayer._svgFactory.createElement(\"path\");\n    defs.append(path);\n    const pathId = `path_p${this.pageIndex}_${id}`;\n    path.setAttribute(\"id\", pathId);\n    path.setAttribute(\"d\", outlines.toSVGPath());\n    if (isPathUpdatable) {\n      this.#toUpdate.set(id, path);\n    }\n    const clipPathId = this.#createClipPath(defs, pathId);\n    const use = DrawLayer._svgFactory.createElement(\"use\");\n    root.append(use);\n    root.setAttribute(\"fill\", color);\n    root.setAttribute(\"fill-opacity\", opacity);\n    use.setAttribute(\"href\", `#${pathId}`);\n    this.#mapping.set(id, root);\n    return {\n      id,\n      clipPathId: `url(#${clipPathId})`\n    };\n  }\n  highlightOutline(outlines) {\n    const id = this.#id++;\n    const root = this.#createSVG(outlines.box);\n    root.classList.add(\"highlightOutline\");\n    const defs = DrawLayer._svgFactory.createElement(\"defs\");\n    root.append(defs);\n    const path = DrawLayer._svgFactory.createElement(\"path\");\n    defs.append(path);\n    const pathId = `path_p${this.pageIndex}_${id}`;\n    path.setAttribute(\"id\", pathId);\n    path.setAttribute(\"d\", outlines.toSVGPath());\n    path.setAttribute(\"vector-effect\", \"non-scaling-stroke\");\n    let maskId;\n    if (outlines.free) {\n      root.classList.add(\"free\");\n      const mask = DrawLayer._svgFactory.createElement(\"mask\");\n      defs.append(mask);\n      maskId = `mask_p${this.pageIndex}_${id}`;\n      mask.setAttribute(\"id\", maskId);\n      mask.setAttribute(\"maskUnits\", \"objectBoundingBox\");\n      const rect = DrawLayer._svgFactory.createElement(\"rect\");\n      mask.append(rect);\n      rect.setAttribute(\"width\", \"1\");\n      rect.setAttribute(\"height\", \"1\");\n      rect.setAttribute(\"fill\", \"white\");\n      const use = DrawLayer._svgFactory.createElement(\"use\");\n      mask.append(use);\n      use.setAttribute(\"href\", `#${pathId}`);\n      use.setAttribute(\"stroke\", \"none\");\n      use.setAttribute(\"fill\", \"black\");\n      use.setAttribute(\"fill-rule\", \"nonzero\");\n      use.classList.add(\"mask\");\n    }\n    const use1 = DrawLayer._svgFactory.createElement(\"use\");\n    root.append(use1);\n    use1.setAttribute(\"href\", `#${pathId}`);\n    if (maskId) {\n      use1.setAttribute(\"mask\", `url(#${maskId})`);\n    }\n    const use2 = use1.cloneNode();\n    root.append(use2);\n    use1.classList.add(\"mainOutline\");\n    use2.classList.add(\"secondaryOutline\");\n    this.#mapping.set(id, root);\n    return id;\n  }\n  finalizeLine(id, line) {\n    const path = this.#toUpdate.get(id);\n    this.#toUpdate.delete(id);\n    this.updateBox(id, line.box);\n    path.setAttribute(\"d\", line.toSVGPath());\n  }\n  updateLine(id, line) {\n    const root = this.#mapping.get(id);\n    const defs = root.firstChild;\n    const path = defs.firstChild;\n    path.setAttribute(\"d\", line.toSVGPath());\n  }\n  removeFreeHighlight(id) {\n    this.remove(id);\n    this.#toUpdate.delete(id);\n  }\n  updatePath(id, line) {\n    this.#toUpdate.get(id).setAttribute(\"d\", line.toSVGPath());\n  }\n  updateBox(id, box) {\n    DrawLayer.#setBox(this.#mapping.get(id), box);\n  }\n  show(id, visible) {\n    this.#mapping.get(id).classList.toggle(\"hidden\", !visible);\n  }\n  rotate(id, angle) {\n    this.#mapping.get(id).setAttribute(\"data-main-rotation\", angle);\n  }\n  changeColor(id, color) {\n    this.#mapping.get(id).setAttribute(\"fill\", color);\n  }\n  changeOpacity(id, opacity) {\n    this.#mapping.get(id).setAttribute(\"fill-opacity\", opacity);\n  }\n  addClass(id, className) {\n    this.#mapping.get(id).classList.add(className);\n  }\n  removeClass(id, className) {\n    this.#mapping.get(id).classList.remove(className);\n  }\n  remove(id) {\n    if (this.#parent === null) {\n      return;\n    }\n    this.#mapping.get(id).remove();\n    this.#mapping.delete(id);\n  }\n  destroy() {\n    this.#parent = null;\n    for (const root of this.#mapping.values()) {\n      root.remove();\n    }\n    this.#mapping.clear();\n  }\n}\n\n\n/***/ }),\n\n/***/ 50:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   XfaText: () => (/* binding */ XfaText)\n/* harmony export */ });\nclass XfaText {\n  static textContent(xfa) {\n    const items = [];\n    const output = {\n      items,\n      styles: Object.create(null)\n    };\n    function walk(node) {\n      if (!node) {\n        return;\n      }\n      let str = null;\n      const name = node.name;\n      if (name === \"#text\") {\n        str = node.value;\n      } else if (!XfaText.shouldBuildText(name)) {\n        return;\n      } else if (node?.attributes?.textContent) {\n        str = node.attributes.textContent;\n      } else if (node.value) {\n        str = node.value;\n      }\n      if (str !== null) {\n        items.push({\n          str\n        });\n      }\n      if (!node.children) {\n        return;\n      }\n      for (const child of node.children) {\n        walk(child);\n      }\n    }\n    walk(xfa);\n    return output;\n  }\n  static shouldBuildText(name) {\n    return !(name === \"textarea\" || name === \"input\" || name === \"option\" || name === \"select\");\n  }\n}\n\n\n/***/ }),\n\n/***/ 61:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   FreeOutliner: () => (/* binding */ FreeOutliner),\n/* harmony export */   Outliner: () => (/* binding */ Outliner)\n/* harmony export */ });\n/* harmony import */ var _shared_util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(292);\n\nclass Outliner {\n  #box;\n  #verticalEdges = [];\n  #intervals = [];\n  constructor(boxes, borderWidth = 0, innerMargin = 0, isLTR = true) {\n    let minX = Infinity;\n    let maxX = -Infinity;\n    let minY = Infinity;\n    let maxY = -Infinity;\n    const NUMBER_OF_DIGITS = 4;\n    const EPSILON = 10 ** -NUMBER_OF_DIGITS;\n    for (const {\n      x,\n      y,\n      width,\n      height\n    } of boxes) {\n      const x1 = Math.floor((x - borderWidth) / EPSILON) * EPSILON;\n      const x2 = Math.ceil((x + width + borderWidth) / EPSILON) * EPSILON;\n      const y1 = Math.floor((y - borderWidth) / EPSILON) * EPSILON;\n      const y2 = Math.ceil((y + height + borderWidth) / EPSILON) * EPSILON;\n      const left = [x1, y1, y2, true];\n      const right = [x2, y1, y2, false];\n      this.#verticalEdges.push(left, right);\n      minX = Math.min(minX, x1);\n      maxX = Math.max(maxX, x2);\n      minY = Math.min(minY, y1);\n      maxY = Math.max(maxY, y2);\n    }\n    const bboxWidth = maxX - minX + 2 * innerMargin;\n    const bboxHeight = maxY - minY + 2 * innerMargin;\n    const shiftedMinX = minX - innerMargin;\n    const shiftedMinY = minY - innerMargin;\n    const lastEdge = this.#verticalEdges.at(isLTR ? -1 : -2);\n    const lastPoint = [lastEdge[0], lastEdge[2]];\n    for (const edge of this.#verticalEdges) {\n      const [x, y1, y2] = edge;\n      edge[0] = (x - shiftedMinX) / bboxWidth;\n      edge[1] = (y1 - shiftedMinY) / bboxHeight;\n      edge[2] = (y2 - shiftedMinY) / bboxHeight;\n    }\n    this.#box = {\n      x: shiftedMinX,\n      y: shiftedMinY,\n      width: bboxWidth,\n      height: bboxHeight,\n      lastPoint\n    };\n  }\n  getOutlines() {\n    this.#verticalEdges.sort((a, b) => a[0] - b[0] || a[1] - b[1] || a[2] - b[2]);\n    const outlineVerticalEdges = [];\n    for (const edge of this.#verticalEdges) {\n      if (edge[3]) {\n        outlineVerticalEdges.push(...this.#breakEdge(edge));\n        this.#insert(edge);\n      } else {\n        this.#remove(edge);\n        outlineVerticalEdges.push(...this.#breakEdge(edge));\n      }\n    }\n    return this.#getOutlines(outlineVerticalEdges);\n  }\n  #getOutlines(outlineVerticalEdges) {\n    const edges = [];\n    const allEdges = new Set();\n    for (const edge of outlineVerticalEdges) {\n      const [x, y1, y2] = edge;\n      edges.push([x, y1, edge], [x, y2, edge]);\n    }\n    edges.sort((a, b) => a[1] - b[1] || a[0] - b[0]);\n    for (let i = 0, ii = edges.length; i < ii; i += 2) {\n      const edge1 = edges[i][2];\n      const edge2 = edges[i + 1][2];\n      edge1.push(edge2);\n      edge2.push(edge1);\n      allEdges.add(edge1);\n      allEdges.add(edge2);\n    }\n    const outlines = [];\n    let outline;\n    while (allEdges.size > 0) {\n      const edge = allEdges.values().next().value;\n      let [x, y1, y2, edge1, edge2] = edge;\n      allEdges.delete(edge);\n      let lastPointX = x;\n      let lastPointY = y1;\n      outline = [x, y2];\n      outlines.push(outline);\n      while (true) {\n        let e;\n        if (allEdges.has(edge1)) {\n          e = edge1;\n        } else if (allEdges.has(edge2)) {\n          e = edge2;\n        } else {\n          break;\n        }\n        allEdges.delete(e);\n        [x, y1, y2, edge1, edge2] = e;\n        if (lastPointX !== x) {\n          outline.push(lastPointX, lastPointY, x, lastPointY === y1 ? y1 : y2);\n          lastPointX = x;\n        }\n        lastPointY = lastPointY === y1 ? y2 : y1;\n      }\n      outline.push(lastPointX, lastPointY);\n    }\n    return new HighlightOutline(outlines, this.#box);\n  }\n  #binarySearch(y) {\n    const array = this.#intervals;\n    let start = 0;\n    let end = array.length - 1;\n    while (start <= end) {\n      const middle = start + end >> 1;\n      const y1 = array[middle][0];\n      if (y1 === y) {\n        return middle;\n      }\n      if (y1 < y) {\n        start = middle + 1;\n      } else {\n        end = middle - 1;\n      }\n    }\n    return end + 1;\n  }\n  #insert([, y1, y2]) {\n    const index = this.#binarySearch(y1);\n    this.#intervals.splice(index, 0, [y1, y2]);\n  }\n  #remove([, y1, y2]) {\n    const index = this.#binarySearch(y1);\n    for (let i = index; i < this.#intervals.length; i++) {\n      const [start, end] = this.#intervals[i];\n      if (start !== y1) {\n        break;\n      }\n      if (start === y1 && end === y2) {\n        this.#intervals.splice(i, 1);\n        return;\n      }\n    }\n    for (let i = index - 1; i >= 0; i--) {\n      const [start, end] = this.#intervals[i];\n      if (start !== y1) {\n        break;\n      }\n      if (start === y1 && end === y2) {\n        this.#intervals.splice(i, 1);\n        return;\n      }\n    }\n  }\n  #breakEdge(edge) {\n    const [x, y1, y2] = edge;\n    const results = [[x, y1, y2]];\n    const index = this.#binarySearch(y2);\n    for (let i = 0; i < index; i++) {\n      const [start, end] = this.#intervals[i];\n      for (let j = 0, jj = results.length; j < jj; j++) {\n        const [, y3, y4] = results[j];\n        if (end <= y3 || y4 <= start) {\n          continue;\n        }\n        if (y3 >= start) {\n          if (y4 > end) {\n            results[j][1] = end;\n          } else {\n            if (jj === 1) {\n              return [];\n            }\n            results.splice(j, 1);\n            j--;\n            jj--;\n          }\n          continue;\n        }\n        results[j][2] = start;\n        if (y4 > end) {\n          results.push([x, end, y4]);\n        }\n      }\n    }\n    return results;\n  }\n}\nclass Outline {\n  toSVGPath() {\n    throw new Error(\"Abstract method `toSVGPath` must be implemented.\");\n  }\n  get box() {\n    throw new Error(\"Abstract getter `box` must be implemented.\");\n  }\n  serialize(_bbox, _rotation) {\n    throw new Error(\"Abstract method `serialize` must be implemented.\");\n  }\n  get free() {\n    return this instanceof FreeHighlightOutline;\n  }\n}\nclass HighlightOutline extends Outline {\n  #box;\n  #outlines;\n  constructor(outlines, box) {\n    super();\n    this.#outlines = outlines;\n    this.#box = box;\n  }\n  toSVGPath() {\n    const buffer = [];\n    for (const polygon of this.#outlines) {\n      let [prevX, prevY] = polygon;\n      buffer.push(`M${prevX} ${prevY}`);\n      for (let i = 2; i < polygon.length; i += 2) {\n        const x = polygon[i];\n        const y = polygon[i + 1];\n        if (x === prevX) {\n          buffer.push(`V${y}`);\n          prevY = y;\n        } else if (y === prevY) {\n          buffer.push(`H${x}`);\n          prevX = x;\n        }\n      }\n      buffer.push(\"Z\");\n    }\n    return buffer.join(\" \");\n  }\n  serialize([blX, blY, trX, trY], _rotation) {\n    const outlines = [];\n    const width = trX - blX;\n    const height = trY - blY;\n    for (const outline of this.#outlines) {\n      const points = new Array(outline.length);\n      for (let i = 0; i < outline.length; i += 2) {\n        points[i] = blX + outline[i] * width;\n        points[i + 1] = trY - outline[i + 1] * height;\n      }\n      outlines.push(points);\n    }\n    return outlines;\n  }\n  get box() {\n    return this.#box;\n  }\n}\nclass FreeOutliner {\n  #box;\n  #bottom = [];\n  #innerMargin;\n  #isLTR;\n  #top = [];\n  #last = new Float64Array(18);\n  #lastX;\n  #lastY;\n  #min;\n  #min_dist;\n  #scaleFactor;\n  #thickness;\n  #points = [];\n  static #MIN_DIST = 8;\n  static #MIN_DIFF = 2;\n  static #MIN = FreeOutliner.#MIN_DIST + FreeOutliner.#MIN_DIFF;\n  constructor({\n    x,\n    y\n  }, box, scaleFactor, thickness, isLTR, innerMargin = 0) {\n    this.#box = box;\n    this.#thickness = thickness * scaleFactor;\n    this.#isLTR = isLTR;\n    this.#last.set([NaN, NaN, NaN, NaN, x, y], 6);\n    this.#innerMargin = innerMargin;\n    this.#min_dist = FreeOutliner.#MIN_DIST * scaleFactor;\n    this.#min = FreeOutliner.#MIN * scaleFactor;\n    this.#scaleFactor = scaleFactor;\n    this.#points.push(x, y);\n  }\n  get free() {\n    return true;\n  }\n  isEmpty() {\n    return isNaN(this.#last[8]);\n  }\n  #getLastCoords() {\n    const lastTop = this.#last.subarray(4, 6);\n    const lastBottom = this.#last.subarray(16, 18);\n    const [x, y, width, height] = this.#box;\n    return [(this.#lastX + (lastTop[0] - lastBottom[0]) / 2 - x) / width, (this.#lastY + (lastTop[1] - lastBottom[1]) / 2 - y) / height, (this.#lastX + (lastBottom[0] - lastTop[0]) / 2 - x) / width, (this.#lastY + (lastBottom[1] - lastTop[1]) / 2 - y) / height];\n  }\n  add({\n    x,\n    y\n  }) {\n    this.#lastX = x;\n    this.#lastY = y;\n    const [layerX, layerY, layerWidth, layerHeight] = this.#box;\n    let [x1, y1, x2, y2] = this.#last.subarray(8, 12);\n    const diffX = x - x2;\n    const diffY = y - y2;\n    const d = Math.hypot(diffX, diffY);\n    if (d < this.#min) {\n      return false;\n    }\n    const diffD = d - this.#min_dist;\n    const K = diffD / d;\n    const shiftX = K * diffX;\n    const shiftY = K * diffY;\n    let x0 = x1;\n    let y0 = y1;\n    x1 = x2;\n    y1 = y2;\n    x2 += shiftX;\n    y2 += shiftY;\n    this.#points?.push(x, y);\n    const nX = -shiftY / diffD;\n    const nY = shiftX / diffD;\n    const thX = nX * this.#thickness;\n    const thY = nY * this.#thickness;\n    this.#last.set(this.#last.subarray(2, 8), 0);\n    this.#last.set([x2 + thX, y2 + thY], 4);\n    this.#last.set(this.#last.subarray(14, 18), 12);\n    this.#last.set([x2 - thX, y2 - thY], 16);\n    if (isNaN(this.#last[6])) {\n      if (this.#top.length === 0) {\n        this.#last.set([x1 + thX, y1 + thY], 2);\n        this.#top.push(NaN, NaN, NaN, NaN, (x1 + thX - layerX) / layerWidth, (y1 + thY - layerY) / layerHeight);\n        this.#last.set([x1 - thX, y1 - thY], 14);\n        this.#bottom.push(NaN, NaN, NaN, NaN, (x1 - thX - layerX) / layerWidth, (y1 - thY - layerY) / layerHeight);\n      }\n      this.#last.set([x0, y0, x1, y1, x2, y2], 6);\n      return !this.isEmpty();\n    }\n    this.#last.set([x0, y0, x1, y1, x2, y2], 6);\n    const angle = Math.abs(Math.atan2(y0 - y1, x0 - x1) - Math.atan2(shiftY, shiftX));\n    if (angle < Math.PI / 2) {\n      [x1, y1, x2, y2] = this.#last.subarray(2, 6);\n      this.#top.push(NaN, NaN, NaN, NaN, ((x1 + x2) / 2 - layerX) / layerWidth, ((y1 + y2) / 2 - layerY) / layerHeight);\n      [x1, y1, x0, y0] = this.#last.subarray(14, 18);\n      this.#bottom.push(NaN, NaN, NaN, NaN, ((x0 + x1) / 2 - layerX) / layerWidth, ((y0 + y1) / 2 - layerY) / layerHeight);\n      return true;\n    }\n    [x0, y0, x1, y1, x2, y2] = this.#last.subarray(0, 6);\n    this.#top.push(((x0 + 5 * x1) / 6 - layerX) / layerWidth, ((y0 + 5 * y1) / 6 - layerY) / layerHeight, ((5 * x1 + x2) / 6 - layerX) / layerWidth, ((5 * y1 + y2) / 6 - layerY) / layerHeight, ((x1 + x2) / 2 - layerX) / layerWidth, ((y1 + y2) / 2 - layerY) / layerHeight);\n    [x2, y2, x1, y1, x0, y0] = this.#last.subarray(12, 18);\n    this.#bottom.push(((x0 + 5 * x1) / 6 - layerX) / layerWidth, ((y0 + 5 * y1) / 6 - layerY) / layerHeight, ((5 * x1 + x2) / 6 - layerX) / layerWidth, ((5 * y1 + y2) / 6 - layerY) / layerHeight, ((x1 + x2) / 2 - layerX) / layerWidth, ((y1 + y2) / 2 - layerY) / layerHeight);\n    return true;\n  }\n  toSVGPath() {\n    if (this.isEmpty()) {\n      return \"\";\n    }\n    const top = this.#top;\n    const bottom = this.#bottom;\n    const lastTop = this.#last.subarray(4, 6);\n    const lastBottom = this.#last.subarray(16, 18);\n    const [x, y, width, height] = this.#box;\n    const [lastTopX, lastTopY, lastBottomX, lastBottomY] = this.#getLastCoords();\n    if (isNaN(this.#last[6]) && !this.isEmpty()) {\n      return `M${(this.#last[2] - x) / width} ${(this.#last[3] - y) / height} L${(this.#last[4] - x) / width} ${(this.#last[5] - y) / height} L${lastTopX} ${lastTopY} L${lastBottomX} ${lastBottomY} L${(this.#last[16] - x) / width} ${(this.#last[17] - y) / height} L${(this.#last[14] - x) / width} ${(this.#last[15] - y) / height} Z`;\n    }\n    const buffer = [];\n    buffer.push(`M${top[4]} ${top[5]}`);\n    for (let i = 6; i < top.length; i += 6) {\n      if (isNaN(top[i])) {\n        buffer.push(`L${top[i + 4]} ${top[i + 5]}`);\n      } else {\n        buffer.push(`C${top[i]} ${top[i + 1]} ${top[i + 2]} ${top[i + 3]} ${top[i + 4]} ${top[i + 5]}`);\n      }\n    }\n    buffer.push(`L${(lastTop[0] - x) / width} ${(lastTop[1] - y) / height} L${lastTopX} ${lastTopY} L${lastBottomX} ${lastBottomY} L${(lastBottom[0] - x) / width} ${(lastBottom[1] - y) / height}`);\n    for (let i = bottom.length - 6; i >= 6; i -= 6) {\n      if (isNaN(bottom[i])) {\n        buffer.push(`L${bottom[i + 4]} ${bottom[i + 5]}`);\n      } else {\n        buffer.push(`C${bottom[i]} ${bottom[i + 1]} ${bottom[i + 2]} ${bottom[i + 3]} ${bottom[i + 4]} ${bottom[i + 5]}`);\n      }\n    }\n    buffer.push(`L${bottom[4]} ${bottom[5]} Z`);\n    return buffer.join(\" \");\n  }\n  getOutlines() {\n    const top = this.#top;\n    const bottom = this.#bottom;\n    const last = this.#last;\n    const lastTop = last.subarray(4, 6);\n    const lastBottom = last.subarray(16, 18);\n    const [layerX, layerY, layerWidth, layerHeight] = this.#box;\n    const points = new Float64Array((this.#points?.length ?? 0) + 2);\n    for (let i = 0, ii = points.length - 2; i < ii; i += 2) {\n      points[i] = (this.#points[i] - layerX) / layerWidth;\n      points[i + 1] = (this.#points[i + 1] - layerY) / layerHeight;\n    }\n    points[points.length - 2] = (this.#lastX - layerX) / layerWidth;\n    points[points.length - 1] = (this.#lastY - layerY) / layerHeight;\n    const [lastTopX, lastTopY, lastBottomX, lastBottomY] = this.#getLastCoords();\n    if (isNaN(last[6]) && !this.isEmpty()) {\n      const outline = new Float64Array(36);\n      outline.set([NaN, NaN, NaN, NaN, (last[2] - layerX) / layerWidth, (last[3] - layerY) / layerHeight, NaN, NaN, NaN, NaN, (last[4] - layerX) / layerWidth, (last[5] - layerY) / layerHeight, NaN, NaN, NaN, NaN, lastTopX, lastTopY, NaN, NaN, NaN, NaN, lastBottomX, lastBottomY, NaN, NaN, NaN, NaN, (last[16] - layerX) / layerWidth, (last[17] - layerY) / layerHeight, NaN, NaN, NaN, NaN, (last[14] - layerX) / layerWidth, (last[15] - layerY) / layerHeight], 0);\n      return new FreeHighlightOutline(outline, points, this.#box, this.#scaleFactor, this.#innerMargin, this.#isLTR);\n    }\n    const outline = new Float64Array(this.#top.length + 24 + this.#bottom.length);\n    let N = top.length;\n    for (let i = 0; i < N; i += 2) {\n      if (isNaN(top[i])) {\n        outline[i] = outline[i + 1] = NaN;\n        continue;\n      }\n      outline[i] = top[i];\n      outline[i + 1] = top[i + 1];\n    }\n    outline.set([NaN, NaN, NaN, NaN, (lastTop[0] - layerX) / layerWidth, (lastTop[1] - layerY) / layerHeight, NaN, NaN, NaN, NaN, lastTopX, lastTopY, NaN, NaN, NaN, NaN, lastBottomX, lastBottomY, NaN, NaN, NaN, NaN, (lastBottom[0] - layerX) / layerWidth, (lastBottom[1] - layerY) / layerHeight], N);\n    N += 24;\n    for (let i = bottom.length - 6; i >= 6; i -= 6) {\n      for (let j = 0; j < 6; j += 2) {\n        if (isNaN(bottom[i + j])) {\n          outline[N] = outline[N + 1] = NaN;\n          N += 2;\n          continue;\n        }\n        outline[N] = bottom[i + j];\n        outline[N + 1] = bottom[i + j + 1];\n        N += 2;\n      }\n    }\n    outline.set([NaN, NaN, NaN, NaN, bottom[4], bottom[5]], N);\n    return new FreeHighlightOutline(outline, points, this.#box, this.#scaleFactor, this.#innerMargin, this.#isLTR);\n  }\n}\nclass FreeHighlightOutline extends Outline {\n  #box;\n  #bbox = null;\n  #innerMargin;\n  #isLTR;\n  #points;\n  #scaleFactor;\n  #outline;\n  constructor(outline, points, box, scaleFactor, innerMargin, isLTR) {\n    super();\n    this.#outline = outline;\n    this.#points = points;\n    this.#box = box;\n    this.#scaleFactor = scaleFactor;\n    this.#innerMargin = innerMargin;\n    this.#isLTR = isLTR;\n    this.#computeMinMax(isLTR);\n    const {\n      x,\n      y,\n      width,\n      height\n    } = this.#bbox;\n    for (let i = 0, ii = outline.length; i < ii; i += 2) {\n      outline[i] = (outline[i] - x) / width;\n      outline[i + 1] = (outline[i + 1] - y) / height;\n    }\n    for (let i = 0, ii = points.length; i < ii; i += 2) {\n      points[i] = (points[i] - x) / width;\n      points[i + 1] = (points[i + 1] - y) / height;\n    }\n  }\n  toSVGPath() {\n    const buffer = [`M${this.#outline[4]} ${this.#outline[5]}`];\n    for (let i = 6, ii = this.#outline.length; i < ii; i += 6) {\n      if (isNaN(this.#outline[i])) {\n        buffer.push(`L${this.#outline[i + 4]} ${this.#outline[i + 5]}`);\n        continue;\n      }\n      buffer.push(`C${this.#outline[i]} ${this.#outline[i + 1]} ${this.#outline[i + 2]} ${this.#outline[i + 3]} ${this.#outline[i + 4]} ${this.#outline[i + 5]}`);\n    }\n    buffer.push(\"Z\");\n    return buffer.join(\" \");\n  }\n  serialize([blX, blY, trX, trY], rotation) {\n    const width = trX - blX;\n    const height = trY - blY;\n    let outline;\n    let points;\n    switch (rotation) {\n      case 0:\n        outline = this.#rescale(this.#outline, blX, trY, width, -height);\n        points = this.#rescale(this.#points, blX, trY, width, -height);\n        break;\n      case 90:\n        outline = this.#rescaleAndSwap(this.#outline, blX, blY, width, height);\n        points = this.#rescaleAndSwap(this.#points, blX, blY, width, height);\n        break;\n      case 180:\n        outline = this.#rescale(this.#outline, trX, blY, -width, height);\n        points = this.#rescale(this.#points, trX, blY, -width, height);\n        break;\n      case 270:\n        outline = this.#rescaleAndSwap(this.#outline, trX, trY, -width, -height);\n        points = this.#rescaleAndSwap(this.#points, trX, trY, -width, -height);\n        break;\n    }\n    return {\n      outline: Array.from(outline),\n      points: [Array.from(points)]\n    };\n  }\n  #rescale(src, tx, ty, sx, sy) {\n    const dest = new Float64Array(src.length);\n    for (let i = 0, ii = src.length; i < ii; i += 2) {\n      dest[i] = tx + src[i] * sx;\n      dest[i + 1] = ty + src[i + 1] * sy;\n    }\n    return dest;\n  }\n  #rescaleAndSwap(src, tx, ty, sx, sy) {\n    const dest = new Float64Array(src.length);\n    for (let i = 0, ii = src.length; i < ii; i += 2) {\n      dest[i] = tx + src[i + 1] * sx;\n      dest[i + 1] = ty + src[i] * sy;\n    }\n    return dest;\n  }\n  #computeMinMax(isLTR) {\n    const outline = this.#outline;\n    let lastX = outline[4];\n    let lastY = outline[5];\n    let minX = lastX;\n    let minY = lastY;\n    let maxX = lastX;\n    let maxY = lastY;\n    let lastPointX = lastX;\n    let lastPointY = lastY;\n    const ltrCallback = isLTR ? Math.max : Math.min;\n    for (let i = 6, ii = outline.length; i < ii; i += 6) {\n      if (isNaN(outline[i])) {\n        minX = Math.min(minX, outline[i + 4]);\n        minY = Math.min(minY, outline[i + 5]);\n        maxX = Math.max(maxX, outline[i + 4]);\n        maxY = Math.max(maxY, outline[i + 5]);\n        if (lastPointY < outline[i + 5]) {\n          lastPointX = outline[i + 4];\n          lastPointY = outline[i + 5];\n        } else if (lastPointY === outline[i + 5]) {\n          lastPointX = ltrCallback(lastPointX, outline[i + 4]);\n        }\n      } else {\n        const bbox = _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.Util.bezierBoundingBox(lastX, lastY, ...outline.slice(i, i + 6));\n        minX = Math.min(minX, bbox[0]);\n        minY = Math.min(minY, bbox[1]);\n        maxX = Math.max(maxX, bbox[2]);\n        maxY = Math.max(maxY, bbox[3]);\n        if (lastPointY < bbox[3]) {\n          lastPointX = bbox[2];\n          lastPointY = bbox[3];\n        } else if (lastPointY === bbox[3]) {\n          lastPointX = ltrCallback(lastPointX, bbox[2]);\n        }\n      }\n      lastX = outline[i + 4];\n      lastY = outline[i + 5];\n    }\n    const x = minX - this.#innerMargin,\n      y = minY - this.#innerMargin,\n      width = maxX - minX + 2 * this.#innerMargin,\n      height = maxY - minY + 2 * this.#innerMargin;\n    this.#bbox = {\n      x,\n      y,\n      width,\n      height,\n      lastPoint: [lastPointX, lastPointY]\n    };\n  }\n  get box() {\n    return this.#bbox;\n  }\n  getNewOutline(thickness, innerMargin) {\n    const {\n      x,\n      y,\n      width,\n      height\n    } = this.#bbox;\n    const [layerX, layerY, layerWidth, layerHeight] = this.#box;\n    const sx = width * layerWidth;\n    const sy = height * layerHeight;\n    const tx = x * layerWidth + layerX;\n    const ty = y * layerHeight + layerY;\n    const outliner = new FreeOutliner({\n      x: this.#points[0] * sx + tx,\n      y: this.#points[1] * sy + ty\n    }, this.#box, this.#scaleFactor, thickness, this.#isLTR, innerMargin ?? this.#innerMargin);\n    for (let i = 2; i < this.#points.length; i += 2) {\n      outliner.add({\n        x: this.#points[i] * sx + tx,\n        y: this.#points[i + 1] * sy + ty\n      });\n    }\n    return outliner.getOutlines();\n  }\n}\n\n\n/***/ }),\n\n/***/ 62:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   Metadata: () => (/* binding */ Metadata)\n/* harmony export */ });\n/* harmony import */ var _shared_util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(292);\n\nclass Metadata {\n  #metadataMap;\n  #data;\n  constructor({\n    parsedData,\n    rawData\n  }) {\n    this.#metadataMap = parsedData;\n    this.#data = rawData;\n  }\n  getRaw() {\n    return this.#data;\n  }\n  get(name) {\n    return this.#metadataMap.get(name) ?? null;\n  }\n  getAll() {\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.objectFromMap)(this.#metadataMap);\n  }\n  has(name) {\n    return this.#metadataMap.has(name);\n  }\n}\n\n\n/***/ }),\n\n/***/ 94:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   PDFFetchStream: () => (/* binding */ PDFFetchStream)\n/* harmony export */ });\n/* harmony import */ var _shared_util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(292);\n/* harmony import */ var _network_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(490);\n\n\nfunction createFetchOptions(headers, withCredentials, abortController) {\n  return {\n    method: \"GET\",\n    headers,\n    signal: abortController.signal,\n    mode: \"cors\",\n    credentials: withCredentials ? \"include\" : \"same-origin\",\n    redirect: \"follow\"\n  };\n}\nfunction createHeaders(httpHeaders) {\n  const headers = new Headers();\n  for (const property in httpHeaders) {\n    const value = httpHeaders[property];\n    if (value === undefined) {\n      continue;\n    }\n    headers.append(property, value);\n  }\n  return headers;\n}\nfunction getArrayBuffer(val) {\n  if (val instanceof Uint8Array) {\n    return val.buffer;\n  }\n  if (val instanceof ArrayBuffer) {\n    return val;\n  }\n  (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(`getArrayBuffer - unexpected data format: ${val}`);\n  return new Uint8Array(val).buffer;\n}\nclass PDFFetchStream {\n  constructor(source) {\n    this.source = source;\n    this.isHttp = /^https?:/i.test(source.url);\n    this.httpHeaders = this.isHttp && source.httpHeaders || {};\n    this._fullRequestReader = null;\n    this._rangeRequestReaders = [];\n  }\n  get _progressiveDataLength() {\n    return this._fullRequestReader?._loaded ?? 0;\n  }\n  getFullReader() {\n    (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.assert)(!this._fullRequestReader, \"PDFFetchStream.getFullReader can only be called once.\");\n    this._fullRequestReader = new PDFFetchStreamReader(this);\n    return this._fullRequestReader;\n  }\n  getRangeReader(begin, end) {\n    if (end <= this._progressiveDataLength) {\n      return null;\n    }\n    const reader = new PDFFetchStreamRangeReader(this, begin, end);\n    this._rangeRequestReaders.push(reader);\n    return reader;\n  }\n  cancelAllRequests(reason) {\n    this._fullRequestReader?.cancel(reason);\n    for (const reader of this._rangeRequestReaders.slice(0)) {\n      reader.cancel(reason);\n    }\n  }\n}\nclass PDFFetchStreamReader {\n  constructor(stream) {\n    this._stream = stream;\n    this._reader = null;\n    this._loaded = 0;\n    this._filename = null;\n    const source = stream.source;\n    this._withCredentials = source.withCredentials || false;\n    this._contentLength = source.length;\n    this._headersCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n    this._disableRange = source.disableRange || false;\n    this._rangeChunkSize = source.rangeChunkSize;\n    if (!this._rangeChunkSize && !this._disableRange) {\n      this._disableRange = true;\n    }\n    this._abortController = new AbortController();\n    this._isStreamingSupported = !source.disableStream;\n    this._isRangeSupported = !source.disableRange;\n    this._headers = createHeaders(this._stream.httpHeaders);\n    const url = source.url;\n    fetch(url, createFetchOptions(this._headers, this._withCredentials, this._abortController)).then(response => {\n      if (!(0,_network_utils_js__WEBPACK_IMPORTED_MODULE_1__.validateResponseStatus)(response.status)) {\n        throw (0,_network_utils_js__WEBPACK_IMPORTED_MODULE_1__.createResponseStatusError)(response.status, url);\n      }\n      this._reader = response.body.getReader();\n      this._headersCapability.resolve();\n      const getResponseHeader = name => response.headers.get(name);\n      const {\n        allowRangeRequests,\n        suggestedLength\n      } = (0,_network_utils_js__WEBPACK_IMPORTED_MODULE_1__.validateRangeRequestCapabilities)({\n        getResponseHeader,\n        isHttp: this._stream.isHttp,\n        rangeChunkSize: this._rangeChunkSize,\n        disableRange: this._disableRange\n      });\n      this._isRangeSupported = allowRangeRequests;\n      this._contentLength = suggestedLength || this._contentLength;\n      this._filename = (0,_network_utils_js__WEBPACK_IMPORTED_MODULE_1__.extractFilenameFromHeader)(getResponseHeader);\n      if (!this._isStreamingSupported && this._isRangeSupported) {\n        this.cancel(new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AbortException(\"Streaming is disabled.\"));\n      }\n    }).catch(this._headersCapability.reject);\n    this.onProgress = null;\n  }\n  get headersReady() {\n    return this._headersCapability.promise;\n  }\n  get filename() {\n    return this._filename;\n  }\n  get contentLength() {\n    return this._contentLength;\n  }\n  get isRangeSupported() {\n    return this._isRangeSupported;\n  }\n  get isStreamingSupported() {\n    return this._isStreamingSupported;\n  }\n  async read() {\n    await this._headersCapability.promise;\n    const {\n      value,\n      done\n    } = await this._reader.read();\n    if (done) {\n      return {\n        value,\n        done\n      };\n    }\n    this._loaded += value.byteLength;\n    this.onProgress?.({\n      loaded: this._loaded,\n      total: this._contentLength\n    });\n    return {\n      value: getArrayBuffer(value),\n      done: false\n    };\n  }\n  cancel(reason) {\n    this._reader?.cancel(reason);\n    this._abortController.abort();\n  }\n}\nclass PDFFetchStreamRangeReader {\n  constructor(stream, begin, end) {\n    this._stream = stream;\n    this._reader = null;\n    this._loaded = 0;\n    const source = stream.source;\n    this._withCredentials = source.withCredentials || false;\n    this._readCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n    this._isStreamingSupported = !source.disableStream;\n    this._abortController = new AbortController();\n    this._headers = createHeaders(this._stream.httpHeaders);\n    this._headers.append(\"Range\", `bytes=${begin}-${end - 1}`);\n    const url = source.url;\n    fetch(url, createFetchOptions(this._headers, this._withCredentials, this._abortController)).then(response => {\n      if (!(0,_network_utils_js__WEBPACK_IMPORTED_MODULE_1__.validateResponseStatus)(response.status)) {\n        throw (0,_network_utils_js__WEBPACK_IMPORTED_MODULE_1__.createResponseStatusError)(response.status, url);\n      }\n      this._readCapability.resolve();\n      this._reader = response.body.getReader();\n    }).catch(this._readCapability.reject);\n    this.onProgress = null;\n  }\n  get isStreamingSupported() {\n    return this._isStreamingSupported;\n  }\n  async read() {\n    await this._readCapability.promise;\n    const {\n      value,\n      done\n    } = await this._reader.read();\n    if (done) {\n      return {\n        value,\n        done\n      };\n    }\n    this._loaded += value.byteLength;\n    this.onProgress?.({\n      loaded: this._loaded\n    });\n    return {\n      value: getArrayBuffer(value),\n      done: false\n    };\n  }\n  cancel(reason) {\n    this._reader?.cancel(reason);\n    this._abortController.abort();\n  }\n}\n\n\n/***/ }),\n\n/***/ 164:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   GlobalWorkerOptions: () => (/* binding */ GlobalWorkerOptions)\n/* harmony export */ });\nclass GlobalWorkerOptions {\n  static #port = null;\n  static #src = \"\";\n  static get workerPort() {\n    return this.#port;\n  }\n  static set workerPort(val) {\n    if (!(typeof Worker !== \"undefined\" && val instanceof Worker) && val !== null) {\n      throw new Error(\"Invalid `workerPort` type.\");\n    }\n    this.#port = val;\n  }\n  static get workerSrc() {\n    return this.#src;\n  }\n  static set workerSrc(val) {\n    if (typeof val !== \"string\") {\n      throw new Error(\"Invalid `workerSrc` type.\");\n    }\n    this.#src = val;\n  }\n}\n\n\n/***/ }),\n\n/***/ 178:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   MessageHandler: () => (/* binding */ MessageHandler)\n/* harmony export */ });\n/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(292);\n\nconst CallbackKind = {\n  UNKNOWN: 0,\n  DATA: 1,\n  ERROR: 2\n};\nconst StreamKind = {\n  UNKNOWN: 0,\n  CANCEL: 1,\n  CANCEL_COMPLETE: 2,\n  CLOSE: 3,\n  ENQUEUE: 4,\n  ERROR: 5,\n  PULL: 6,\n  PULL_COMPLETE: 7,\n  START_COMPLETE: 8\n};\nfunction wrapReason(reason) {\n  if (!(reason instanceof Error || typeof reason === \"object\" && reason !== null)) {\n    (0,_util_js__WEBPACK_IMPORTED_MODULE_0__.unreachable)('wrapReason: Expected \"reason\" to be a (possibly cloned) Error.');\n  }\n  switch (reason.name) {\n    case \"AbortException\":\n      return new _util_js__WEBPACK_IMPORTED_MODULE_0__.AbortException(reason.message);\n    case \"MissingPDFException\":\n      return new _util_js__WEBPACK_IMPORTED_MODULE_0__.MissingPDFException(reason.message);\n    case \"PasswordException\":\n      return new _util_js__WEBPACK_IMPORTED_MODULE_0__.PasswordException(reason.message, reason.code);\n    case \"UnexpectedResponseException\":\n      return new _util_js__WEBPACK_IMPORTED_MODULE_0__.UnexpectedResponseException(reason.message, reason.status);\n    case \"UnknownErrorException\":\n      return new _util_js__WEBPACK_IMPORTED_MODULE_0__.UnknownErrorException(reason.message, reason.details);\n    default:\n      return new _util_js__WEBPACK_IMPORTED_MODULE_0__.UnknownErrorException(reason.message, reason.toString());\n  }\n}\nclass MessageHandler {\n  constructor(sourceName, targetName, comObj) {\n    this.sourceName = sourceName;\n    this.targetName = targetName;\n    this.comObj = comObj;\n    this.callbackId = 1;\n    this.streamId = 1;\n    this.streamSinks = Object.create(null);\n    this.streamControllers = Object.create(null);\n    this.callbackCapabilities = Object.create(null);\n    this.actionHandler = Object.create(null);\n    this._onComObjOnMessage = event => {\n      const data = event.data;\n      if (data.targetName !== this.sourceName) {\n        return;\n      }\n      if (data.stream) {\n        this.#processStreamMessage(data);\n        return;\n      }\n      if (data.callback) {\n        const callbackId = data.callbackId;\n        const capability = this.callbackCapabilities[callbackId];\n        if (!capability) {\n          throw new Error(`Cannot resolve callback ${callbackId}`);\n        }\n        delete this.callbackCapabilities[callbackId];\n        if (data.callback === CallbackKind.DATA) {\n          capability.resolve(data.data);\n        } else if (data.callback === CallbackKind.ERROR) {\n          capability.reject(wrapReason(data.reason));\n        } else {\n          throw new Error(\"Unexpected callback case\");\n        }\n        return;\n      }\n      const action = this.actionHandler[data.action];\n      if (!action) {\n        throw new Error(`Unknown action from worker: ${data.action}`);\n      }\n      if (data.callbackId) {\n        const cbSourceName = this.sourceName;\n        const cbTargetName = data.sourceName;\n        new Promise(function (resolve) {\n          resolve(action(data.data));\n        }).then(function (result) {\n          comObj.postMessage({\n            sourceName: cbSourceName,\n            targetName: cbTargetName,\n            callback: CallbackKind.DATA,\n            callbackId: data.callbackId,\n            data: result\n          });\n        }, function (reason) {\n          comObj.postMessage({\n            sourceName: cbSourceName,\n            targetName: cbTargetName,\n            callback: CallbackKind.ERROR,\n            callbackId: data.callbackId,\n            reason: wrapReason(reason)\n          });\n        });\n        return;\n      }\n      if (data.streamId) {\n        this.#createStreamSink(data);\n        return;\n      }\n      action(data.data);\n    };\n    comObj.addEventListener(\"message\", this._onComObjOnMessage);\n  }\n  on(actionName, handler) {\n    const ah = this.actionHandler;\n    if (ah[actionName]) {\n      throw new Error(`There is already an actionName called \"${actionName}\"`);\n    }\n    ah[actionName] = handler;\n  }\n  send(actionName, data, transfers) {\n    this.comObj.postMessage({\n      sourceName: this.sourceName,\n      targetName: this.targetName,\n      action: actionName,\n      data\n    }, transfers);\n  }\n  sendWithPromise(actionName, data, transfers) {\n    const callbackId = this.callbackId++;\n    const capability = new _util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n    this.callbackCapabilities[callbackId] = capability;\n    try {\n      this.comObj.postMessage({\n        sourceName: this.sourceName,\n        targetName: this.targetName,\n        action: actionName,\n        callbackId,\n        data\n      }, transfers);\n    } catch (ex) {\n      capability.reject(ex);\n    }\n    return capability.promise;\n  }\n  sendWithStream(actionName, data, queueingStrategy, transfers) {\n    const streamId = this.streamId++,\n      sourceName = this.sourceName,\n      targetName = this.targetName,\n      comObj = this.comObj;\n    return new ReadableStream({\n      start: controller => {\n        const startCapability = new _util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n        this.streamControllers[streamId] = {\n          controller,\n          startCall: startCapability,\n          pullCall: null,\n          cancelCall: null,\n          isClosed: false\n        };\n        comObj.postMessage({\n          sourceName,\n          targetName,\n          action: actionName,\n          streamId,\n          data,\n          desiredSize: controller.desiredSize\n        }, transfers);\n        return startCapability.promise;\n      },\n      pull: controller => {\n        const pullCapability = new _util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n        this.streamControllers[streamId].pullCall = pullCapability;\n        comObj.postMessage({\n          sourceName,\n          targetName,\n          stream: StreamKind.PULL,\n          streamId,\n          desiredSize: controller.desiredSize\n        });\n        return pullCapability.promise;\n      },\n      cancel: reason => {\n        (0,_util_js__WEBPACK_IMPORTED_MODULE_0__.assert)(reason instanceof Error, \"cancel must have a valid reason\");\n        const cancelCapability = new _util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n        this.streamControllers[streamId].cancelCall = cancelCapability;\n        this.streamControllers[streamId].isClosed = true;\n        comObj.postMessage({\n          sourceName,\n          targetName,\n          stream: StreamKind.CANCEL,\n          streamId,\n          reason: wrapReason(reason)\n        });\n        return cancelCapability.promise;\n      }\n    }, queueingStrategy);\n  }\n  #createStreamSink(data) {\n    const streamId = data.streamId,\n      sourceName = this.sourceName,\n      targetName = data.sourceName,\n      comObj = this.comObj;\n    const self = this,\n      action = this.actionHandler[data.action];\n    const streamSink = {\n      enqueue(chunk, size = 1, transfers) {\n        if (this.isCancelled) {\n          return;\n        }\n        const lastDesiredSize = this.desiredSize;\n        this.desiredSize -= size;\n        if (lastDesiredSize > 0 && this.desiredSize <= 0) {\n          this.sinkCapability = new _util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n          this.ready = this.sinkCapability.promise;\n        }\n        comObj.postMessage({\n          sourceName,\n          targetName,\n          stream: StreamKind.ENQUEUE,\n          streamId,\n          chunk\n        }, transfers);\n      },\n      close() {\n        if (this.isCancelled) {\n          return;\n        }\n        this.isCancelled = true;\n        comObj.postMessage({\n          sourceName,\n          targetName,\n          stream: StreamKind.CLOSE,\n          streamId\n        });\n        delete self.streamSinks[streamId];\n      },\n      error(reason) {\n        (0,_util_js__WEBPACK_IMPORTED_MODULE_0__.assert)(reason instanceof Error, \"error must have a valid reason\");\n        if (this.isCancelled) {\n          return;\n        }\n        this.isCancelled = true;\n        comObj.postMessage({\n          sourceName,\n          targetName,\n          stream: StreamKind.ERROR,\n          streamId,\n          reason: wrapReason(reason)\n        });\n      },\n      sinkCapability: new _util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability(),\n      onPull: null,\n      onCancel: null,\n      isCancelled: false,\n      desiredSize: data.desiredSize,\n      ready: null\n    };\n    streamSink.sinkCapability.resolve();\n    streamSink.ready = streamSink.sinkCapability.promise;\n    this.streamSinks[streamId] = streamSink;\n    new Promise(function (resolve) {\n      resolve(action(data.data, streamSink));\n    }).then(function () {\n      comObj.postMessage({\n        sourceName,\n        targetName,\n        stream: StreamKind.START_COMPLETE,\n        streamId,\n        success: true\n      });\n    }, function (reason) {\n      comObj.postMessage({\n        sourceName,\n        targetName,\n        stream: StreamKind.START_COMPLETE,\n        streamId,\n        reason: wrapReason(reason)\n      });\n    });\n  }\n  #processStreamMessage(data) {\n    const streamId = data.streamId,\n      sourceName = this.sourceName,\n      targetName = data.sourceName,\n      comObj = this.comObj;\n    const streamController = this.streamControllers[streamId],\n      streamSink = this.streamSinks[streamId];\n    switch (data.stream) {\n      case StreamKind.START_COMPLETE:\n        if (data.success) {\n          streamController.startCall.resolve();\n        } else {\n          streamController.startCall.reject(wrapReason(data.reason));\n        }\n        break;\n      case StreamKind.PULL_COMPLETE:\n        if (data.success) {\n          streamController.pullCall.resolve();\n        } else {\n          streamController.pullCall.reject(wrapReason(data.reason));\n        }\n        break;\n      case StreamKind.PULL:\n        if (!streamSink) {\n          comObj.postMessage({\n            sourceName,\n            targetName,\n            stream: StreamKind.PULL_COMPLETE,\n            streamId,\n            success: true\n          });\n          break;\n        }\n        if (streamSink.desiredSize <= 0 && data.desiredSize > 0) {\n          streamSink.sinkCapability.resolve();\n        }\n        streamSink.desiredSize = data.desiredSize;\n        new Promise(function (resolve) {\n          resolve(streamSink.onPull?.());\n        }).then(function () {\n          comObj.postMessage({\n            sourceName,\n            targetName,\n            stream: StreamKind.PULL_COMPLETE,\n            streamId,\n            success: true\n          });\n        }, function (reason) {\n          comObj.postMessage({\n            sourceName,\n            targetName,\n            stream: StreamKind.PULL_COMPLETE,\n            streamId,\n            reason: wrapReason(reason)\n          });\n        });\n        break;\n      case StreamKind.ENQUEUE:\n        (0,_util_js__WEBPACK_IMPORTED_MODULE_0__.assert)(streamController, \"enqueue should have stream controller\");\n        if (streamController.isClosed) {\n          break;\n        }\n        streamController.controller.enqueue(data.chunk);\n        break;\n      case StreamKind.CLOSE:\n        (0,_util_js__WEBPACK_IMPORTED_MODULE_0__.assert)(streamController, \"close should have stream controller\");\n        if (streamController.isClosed) {\n          break;\n        }\n        streamController.isClosed = true;\n        streamController.controller.close();\n        this.#deleteStreamController(streamController, streamId);\n        break;\n      case StreamKind.ERROR:\n        (0,_util_js__WEBPACK_IMPORTED_MODULE_0__.assert)(streamController, \"error should have stream controller\");\n        streamController.controller.error(wrapReason(data.reason));\n        this.#deleteStreamController(streamController, streamId);\n        break;\n      case StreamKind.CANCEL_COMPLETE:\n        if (data.success) {\n          streamController.cancelCall.resolve();\n        } else {\n          streamController.cancelCall.reject(wrapReason(data.reason));\n        }\n        this.#deleteStreamController(streamController, streamId);\n        break;\n      case StreamKind.CANCEL:\n        if (!streamSink) {\n          break;\n        }\n        new Promise(function (resolve) {\n          resolve(streamSink.onCancel?.(wrapReason(data.reason)));\n        }).then(function () {\n          comObj.postMessage({\n            sourceName,\n            targetName,\n            stream: StreamKind.CANCEL_COMPLETE,\n            streamId,\n            success: true\n          });\n        }, function (reason) {\n          comObj.postMessage({\n            sourceName,\n            targetName,\n            stream: StreamKind.CANCEL_COMPLETE,\n            streamId,\n            reason: wrapReason(reason)\n          });\n        });\n        streamSink.sinkCapability.reject(wrapReason(data.reason));\n        streamSink.isCancelled = true;\n        delete this.streamSinks[streamId];\n        break;\n      default:\n        throw new Error(\"Unexpected stream case\");\n    }\n  }\n  async #deleteStreamController(streamController, streamId) {\n    await Promise.allSettled([streamController.startCall?.promise, streamController.pullCall?.promise, streamController.cancelCall?.promise]);\n    delete this.streamControllers[streamId];\n  }\n  destroy() {\n    this.comObj.removeEventListener(\"message\", this._onComObjOnMessage);\n  }\n}\n\n\n/***/ }),\n\n/***/ 228:\n/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   AbortException: () => (/* reexport safe */ _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AbortException),\n/* harmony export */   AnnotationEditorLayer: () => (/* reexport safe */ _display_editor_annotation_editor_layer_js__WEBPACK_IMPORTED_MODULE_4__.AnnotationEditorLayer),\n/* harmony export */   AnnotationEditorParamsType: () => (/* reexport safe */ _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType),\n/* harmony export */   AnnotationEditorType: () => (/* reexport safe */ _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType),\n/* harmony export */   AnnotationEditorUIManager: () => (/* reexport safe */ _display_editor_tools_js__WEBPACK_IMPORTED_MODULE_5__.AnnotationEditorUIManager),\n/* harmony export */   AnnotationLayer: () => (/* reexport safe */ _display_annotation_layer_js__WEBPACK_IMPORTED_MODULE_6__.AnnotationLayer),\n/* harmony export */   AnnotationMode: () => (/* reexport safe */ _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode),\n/* harmony export */   CMapCompressionType: () => (/* reexport safe */ _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.CMapCompressionType),\n/* harmony export */   ColorPicker: () => (/* reexport safe */ _display_editor_color_picker_js__WEBPACK_IMPORTED_MODULE_7__.ColorPicker),\n/* harmony export */   DOMSVGFactory: () => (/* reexport safe */ _display_display_utils_js__WEBPACK_IMPORTED_MODULE_2__.DOMSVGFactory),\n/* harmony export */   DrawLayer: () => (/* reexport safe */ _display_draw_layer_js__WEBPACK_IMPORTED_MODULE_8__.DrawLayer),\n/* harmony export */   FeatureTest: () => (/* reexport safe */ _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.FeatureTest),\n/* harmony export */   GlobalWorkerOptions: () => (/* reexport safe */ _display_worker_options_js__WEBPACK_IMPORTED_MODULE_10__.GlobalWorkerOptions),\n/* harmony export */   ImageKind: () => (/* reexport safe */ _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.ImageKind),\n/* harmony export */   InvalidPDFException: () => (/* reexport safe */ _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.InvalidPDFException),\n/* harmony export */   MissingPDFException: () => (/* reexport safe */ _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.MissingPDFException),\n/* harmony export */   OPS: () => (/* reexport safe */ _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.OPS),\n/* harmony export */   Outliner: () => (/* reexport safe */ _display_editor_outliner_js__WEBPACK_IMPORTED_MODULE_9__.Outliner),\n/* harmony export */   PDFDataRangeTransport: () => (/* reexport safe */ _display_api_js__WEBPACK_IMPORTED_MODULE_1__.PDFDataRangeTransport),\n/* harmony export */   PDFDateString: () => (/* reexport safe */ _display_display_utils_js__WEBPACK_IMPORTED_MODULE_2__.PDFDateString),\n/* harmony export */   PDFWorker: () => (/* reexport safe */ _display_api_js__WEBPACK_IMPORTED_MODULE_1__.PDFWorker),\n/* harmony export */   PasswordResponses: () => (/* reexport safe */ _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PasswordResponses),\n/* harmony export */   PermissionFlag: () => (/* reexport safe */ _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PermissionFlag),\n/* harmony export */   PixelsPerInch: () => (/* reexport safe */ _display_display_utils_js__WEBPACK_IMPORTED_MODULE_2__.PixelsPerInch),\n/* harmony export */   PromiseCapability: () => (/* reexport safe */ _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability),\n/* harmony export */   RenderingCancelledException: () => (/* reexport safe */ _display_display_utils_js__WEBPACK_IMPORTED_MODULE_2__.RenderingCancelledException),\n/* harmony export */   UnexpectedResponseException: () => (/* reexport safe */ _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.UnexpectedResponseException),\n/* harmony export */   Util: () => (/* reexport safe */ _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.Util),\n/* harmony export */   VerbosityLevel: () => (/* reexport safe */ _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.VerbosityLevel),\n/* harmony export */   XfaLayer: () => (/* reexport safe */ _display_xfa_layer_js__WEBPACK_IMPORTED_MODULE_11__.XfaLayer),\n/* harmony export */   build: () => (/* reexport safe */ _display_api_js__WEBPACK_IMPORTED_MODULE_1__.build),\n/* harmony export */   createValidAbsoluteUrl: () => (/* reexport safe */ _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.createValidAbsoluteUrl),\n/* harmony export */   fetchData: () => (/* reexport safe */ _display_display_utils_js__WEBPACK_IMPORTED_MODULE_2__.fetchData),\n/* harmony export */   getDocument: () => (/* reexport safe */ _display_api_js__WEBPACK_IMPORTED_MODULE_1__.getDocument),\n/* harmony export */   getFilenameFromUrl: () => (/* reexport safe */ _display_display_utils_js__WEBPACK_IMPORTED_MODULE_2__.getFilenameFromUrl),\n/* harmony export */   getPdfFilenameFromUrl: () => (/* reexport safe */ _display_display_utils_js__WEBPACK_IMPORTED_MODULE_2__.getPdfFilenameFromUrl),\n/* harmony export */   getXfaPageViewport: () => (/* reexport safe */ _display_display_utils_js__WEBPACK_IMPORTED_MODULE_2__.getXfaPageViewport),\n/* harmony export */   isDataScheme: () => (/* reexport safe */ _display_display_utils_js__WEBPACK_IMPORTED_MODULE_2__.isDataScheme),\n/* harmony export */   isPdfFile: () => (/* reexport safe */ _display_display_utils_js__WEBPACK_IMPORTED_MODULE_2__.isPdfFile),\n/* harmony export */   noContextMenu: () => (/* reexport safe */ _display_display_utils_js__WEBPACK_IMPORTED_MODULE_2__.noContextMenu),\n/* harmony export */   normalizeUnicode: () => (/* reexport safe */ _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.normalizeUnicode),\n/* harmony export */   renderTextLayer: () => (/* reexport safe */ _display_text_layer_js__WEBPACK_IMPORTED_MODULE_3__.renderTextLayer),\n/* harmony export */   setLayerDimensions: () => (/* reexport safe */ _display_display_utils_js__WEBPACK_IMPORTED_MODULE_2__.setLayerDimensions),\n/* harmony export */   shadow: () => (/* reexport safe */ _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.shadow),\n/* harmony export */   updateTextLayer: () => (/* reexport safe */ _display_text_layer_js__WEBPACK_IMPORTED_MODULE_3__.updateTextLayer),\n/* harmony export */   version: () => (/* reexport safe */ _display_api_js__WEBPACK_IMPORTED_MODULE_1__.version)\n/* harmony export */ });\n/* harmony import */ var _shared_util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(292);\n/* harmony import */ var _display_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(831);\n/* harmony import */ var _display_display_utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(419);\n/* harmony import */ var _display_text_layer_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(814);\n/* harmony import */ var _display_editor_annotation_editor_layer_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(731);\n/* harmony import */ var _display_editor_tools_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(830);\n/* harmony import */ var _display_annotation_layer_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(976);\n/* harmony import */ var _display_editor_color_picker_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(259);\n/* harmony import */ var _display_draw_layer_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(47);\n/* harmony import */ var _display_worker_options_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(164);\n/* harmony import */ var _display_editor_outliner_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(61);\n/* harmony import */ var _display_xfa_layer_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(284);\nvar __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_display_api_js__WEBPACK_IMPORTED_MODULE_1__]);\n_display_api_js__WEBPACK_IMPORTED_MODULE_1__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];\n\n\n\n\n\n\n\n\n\n\n\n\nconst pdfjsVersion = \"4.1.0\";\nconst pdfjsBuild = \"849f8548b1\";\n\n__webpack_async_result__();\n} catch(e) { __webpack_async_result__(e); } });\n\n/***/ }),\n\n/***/ 259:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   ColorPicker: () => (/* binding */ ColorPicker)\n/* harmony export */ });\n/* harmony import */ var _shared_util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(292);\n/* harmony import */ var _tools_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(830);\n/* harmony import */ var _display_utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(419);\n\n\n\nclass ColorPicker {\n  #boundKeyDown = this.#keyDown.bind(this);\n  #boundPointerDown = this.#pointerDown.bind(this);\n  #button = null;\n  #buttonSwatch = null;\n  #defaultColor;\n  #dropdown = null;\n  #dropdownWasFromKeyboard = false;\n  #isMainColorPicker = false;\n  #editor = null;\n  #eventBus;\n  #uiManager = null;\n  #type;\n  static get _keyboardManager() {\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, \"_keyboardManager\", new _tools_js__WEBPACK_IMPORTED_MODULE_1__.KeyboardManager([[[\"Escape\", \"mac+Escape\"], ColorPicker.prototype._hideDropdownFromKeyboard], [[\" \", \"mac+ \"], ColorPicker.prototype._colorSelectFromKeyboard], [[\"ArrowDown\", \"ArrowRight\", \"mac+ArrowDown\", \"mac+ArrowRight\"], ColorPicker.prototype._moveToNext], [[\"ArrowUp\", \"ArrowLeft\", \"mac+ArrowUp\", \"mac+ArrowLeft\"], ColorPicker.prototype._moveToPrevious], [[\"Home\", \"mac+Home\"], ColorPicker.prototype._moveToBeginning], [[\"End\", \"mac+End\"], ColorPicker.prototype._moveToEnd]]));\n  }\n  constructor({\n    editor = null,\n    uiManager = null\n  }) {\n    if (editor) {\n      this.#isMainColorPicker = false;\n      this.#type = _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType.HIGHLIGHT_COLOR;\n      this.#editor = editor;\n    } else {\n      this.#isMainColorPicker = true;\n      this.#type = _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType.HIGHLIGHT_DEFAULT_COLOR;\n    }\n    this.#uiManager = editor?._uiManager || uiManager;\n    this.#eventBus = this.#uiManager._eventBus;\n    this.#defaultColor = editor?.color || this.#uiManager?.highlightColors.values().next().value || \"#FFFF98\";\n  }\n  renderButton() {\n    const button = this.#button = document.createElement(\"button\");\n    button.className = \"colorPicker\";\n    button.tabIndex = \"0\";\n    button.setAttribute(\"data-l10n-id\", \"pdfjs-editor-colorpicker-button\");\n    button.setAttribute(\"aria-haspopup\", true);\n    button.addEventListener(\"click\", this.#openDropdown.bind(this));\n    button.addEventListener(\"keydown\", this.#boundKeyDown);\n    const swatch = this.#buttonSwatch = document.createElement(\"span\");\n    swatch.className = \"swatch\";\n    swatch.setAttribute(\"aria-hidden\", true);\n    swatch.style.backgroundColor = this.#defaultColor;\n    button.append(swatch);\n    return button;\n  }\n  renderMainDropdown() {\n    const dropdown = this.#dropdown = this.#getDropdownRoot();\n    dropdown.setAttribute(\"aria-orientation\", \"horizontal\");\n    dropdown.setAttribute(\"aria-labelledby\", \"highlightColorPickerLabel\");\n    return dropdown;\n  }\n  #getDropdownRoot() {\n    const div = document.createElement(\"div\");\n    div.addEventListener(\"contextmenu\", _display_utils_js__WEBPACK_IMPORTED_MODULE_2__.noContextMenu);\n    div.className = \"dropdown\";\n    div.role = \"listbox\";\n    div.setAttribute(\"aria-multiselectable\", false);\n    div.setAttribute(\"aria-orientation\", \"vertical\");\n    div.setAttribute(\"data-l10n-id\", \"pdfjs-editor-colorpicker-dropdown\");\n    for (const [name, color] of this.#uiManager.highlightColors) {\n      const button = document.createElement(\"button\");\n      button.tabIndex = \"0\";\n      button.role = \"option\";\n      button.setAttribute(\"data-color\", color);\n      button.title = name;\n      button.setAttribute(\"data-l10n-id\", `pdfjs-editor-colorpicker-${name}`);\n      const swatch = document.createElement(\"span\");\n      button.append(swatch);\n      swatch.className = \"swatch\";\n      swatch.style.backgroundColor = color;\n      button.setAttribute(\"aria-selected\", color === this.#defaultColor);\n      button.addEventListener(\"click\", this.#colorSelect.bind(this, color));\n      div.append(button);\n    }\n    div.addEventListener(\"keydown\", this.#boundKeyDown);\n    return div;\n  }\n  #colorSelect(color, event) {\n    event.stopPropagation();\n    this.#eventBus.dispatch(\"switchannotationeditorparams\", {\n      source: this,\n      type: this.#type,\n      value: color\n    });\n  }\n  _colorSelectFromKeyboard(event) {\n    if (event.target === this.#button) {\n      this.#openDropdown(event);\n      return;\n    }\n    const color = event.target.getAttribute(\"data-color\");\n    if (!color) {\n      return;\n    }\n    this.#colorSelect(color, event);\n  }\n  _moveToNext(event) {\n    if (!this.#isDropdownVisible) {\n      this.#openDropdown(event);\n      return;\n    }\n    if (event.target === this.#button) {\n      this.#dropdown.firstChild?.focus();\n      return;\n    }\n    event.target.nextSibling?.focus();\n  }\n  _moveToPrevious(event) {\n    if (event.target === this.#dropdown?.firstChild || event.target === this.#button) {\n      if (this.#isDropdownVisible) {\n        this._hideDropdownFromKeyboard();\n      }\n      return;\n    }\n    if (!this.#isDropdownVisible) {\n      this.#openDropdown(event);\n    }\n    event.target.previousSibling?.focus();\n  }\n  _moveToBeginning(event) {\n    if (!this.#isDropdownVisible) {\n      this.#openDropdown(event);\n      return;\n    }\n    this.#dropdown.firstChild?.focus();\n  }\n  _moveToEnd(event) {\n    if (!this.#isDropdownVisible) {\n      this.#openDropdown(event);\n      return;\n    }\n    this.#dropdown.lastChild?.focus();\n  }\n  #keyDown(event) {\n    ColorPicker._keyboardManager.exec(this, event);\n  }\n  #openDropdown(event) {\n    if (this.#isDropdownVisible) {\n      this.hideDropdown();\n      return;\n    }\n    this.#dropdownWasFromKeyboard = event.detail === 0;\n    window.addEventListener(\"pointerdown\", this.#boundPointerDown);\n    if (this.#dropdown) {\n      this.#dropdown.classList.remove(\"hidden\");\n      return;\n    }\n    const root = this.#dropdown = this.#getDropdownRoot();\n    this.#button.append(root);\n  }\n  #pointerDown(event) {\n    if (this.#dropdown?.contains(event.target)) {\n      return;\n    }\n    this.hideDropdown();\n  }\n  hideDropdown() {\n    this.#dropdown?.classList.add(\"hidden\");\n    window.removeEventListener(\"pointerdown\", this.#boundPointerDown);\n  }\n  get #isDropdownVisible() {\n    return this.#dropdown && !this.#dropdown.classList.contains(\"hidden\");\n  }\n  _hideDropdownFromKeyboard() {\n    if (this.#isMainColorPicker) {\n      return;\n    }\n    if (!this.#isDropdownVisible) {\n      this.#editor?.unselect();\n      return;\n    }\n    this.hideDropdown();\n    this.#button.focus({\n      preventScroll: true,\n      focusVisible: this.#dropdownWasFromKeyboard\n    });\n  }\n  updateColor(color) {\n    if (this.#buttonSwatch) {\n      this.#buttonSwatch.style.backgroundColor = color;\n    }\n    if (!this.#dropdown) {\n      return;\n    }\n    const i = this.#uiManager.highlightColors.values();\n    for (const child of this.#dropdown.children) {\n      child.setAttribute(\"aria-selected\", i.next().value === color);\n    }\n  }\n  destroy() {\n    this.#button?.remove();\n    this.#button = null;\n    this.#buttonSwatch = null;\n    this.#dropdown?.remove();\n    this.#dropdown = null;\n  }\n}\n\n\n/***/ }),\n\n/***/ 284:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   XfaLayer: () => (/* binding */ XfaLayer)\n/* harmony export */ });\n/* harmony import */ var _xfa_text_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50);\n\nclass XfaLayer {\n  static setupStorage(html, id, element, storage, intent) {\n    const storedData = storage.getValue(id, {\n      value: null\n    });\n    switch (element.name) {\n      case \"textarea\":\n        if (storedData.value !== null) {\n          html.textContent = storedData.value;\n        }\n        if (intent === \"print\") {\n          break;\n        }\n        html.addEventListener(\"input\", event => {\n          storage.setValue(id, {\n            value: event.target.value\n          });\n        });\n        break;\n      case \"input\":\n        if (element.attributes.type === \"radio\" || element.attributes.type === \"checkbox\") {\n          if (storedData.value === element.attributes.xfaOn) {\n            html.setAttribute(\"checked\", true);\n          } else if (storedData.value === element.attributes.xfaOff) {\n            html.removeAttribute(\"checked\");\n          }\n          if (intent === \"print\") {\n            break;\n          }\n          html.addEventListener(\"change\", event => {\n            storage.setValue(id, {\n              value: event.target.checked ? event.target.getAttribute(\"xfaOn\") : event.target.getAttribute(\"xfaOff\")\n            });\n          });\n        } else {\n          if (storedData.value !== null) {\n            html.setAttribute(\"value\", storedData.value);\n          }\n          if (intent === \"print\") {\n            break;\n          }\n          html.addEventListener(\"input\", event => {\n            storage.setValue(id, {\n              value: event.target.value\n            });\n          });\n        }\n        break;\n      case \"select\":\n        if (storedData.value !== null) {\n          html.setAttribute(\"value\", storedData.value);\n          for (const option of element.children) {\n            if (option.attributes.value === storedData.value) {\n              option.attributes.selected = true;\n            } else if (option.attributes.hasOwnProperty(\"selected\")) {\n              delete option.attributes.selected;\n            }\n          }\n        }\n        html.addEventListener(\"input\", event => {\n          const options = event.target.options;\n          const value = options.selectedIndex === -1 ? \"\" : options[options.selectedIndex].value;\n          storage.setValue(id, {\n            value\n          });\n        });\n        break;\n    }\n  }\n  static setAttributes({\n    html,\n    element,\n    storage = null,\n    intent,\n    linkService\n  }) {\n    const {\n      attributes\n    } = element;\n    const isHTMLAnchorElement = html instanceof HTMLAnchorElement;\n    if (attributes.type === \"radio\") {\n      attributes.name = `${attributes.name}-${intent}`;\n    }\n    for (const [key, value] of Object.entries(attributes)) {\n      if (value === null || value === undefined) {\n        continue;\n      }\n      switch (key) {\n        case \"class\":\n          if (value.length) {\n            html.setAttribute(key, value.join(\" \"));\n          }\n          break;\n        case \"dataId\":\n          break;\n        case \"id\":\n          html.setAttribute(\"data-element-id\", value);\n          break;\n        case \"style\":\n          Object.assign(html.style, value);\n          break;\n        case \"textContent\":\n          html.textContent = value;\n          break;\n        default:\n          if (!isHTMLAnchorElement || key !== \"href\" && key !== \"newWindow\") {\n            html.setAttribute(key, value);\n          }\n      }\n    }\n    if (isHTMLAnchorElement) {\n      linkService.addLinkAttributes(html, attributes.href, attributes.newWindow);\n    }\n    if (storage && attributes.dataId) {\n      this.setupStorage(html, attributes.dataId, element, storage);\n    }\n  }\n  static render(parameters) {\n    const storage = parameters.annotationStorage;\n    const linkService = parameters.linkService;\n    const root = parameters.xfaHtml;\n    const intent = parameters.intent || \"display\";\n    const rootHtml = document.createElement(root.name);\n    if (root.attributes) {\n      this.setAttributes({\n        html: rootHtml,\n        element: root,\n        intent,\n        linkService\n      });\n    }\n    const isNotForRichText = intent !== \"richText\";\n    const rootDiv = parameters.div;\n    rootDiv.append(rootHtml);\n    if (parameters.viewport) {\n      const transform = `matrix(${parameters.viewport.transform.join(\",\")})`;\n      rootDiv.style.transform = transform;\n    }\n    if (isNotForRichText) {\n      rootDiv.setAttribute(\"class\", \"xfaLayer xfaFont\");\n    }\n    const textDivs = [];\n    if (root.children.length === 0) {\n      if (root.value) {\n        const node = document.createTextNode(root.value);\n        rootHtml.append(node);\n        if (isNotForRichText && _xfa_text_js__WEBPACK_IMPORTED_MODULE_0__.XfaText.shouldBuildText(root.name)) {\n          textDivs.push(node);\n        }\n      }\n      return {\n        textDivs\n      };\n    }\n    const stack = [[root, -1, rootHtml]];\n    while (stack.length > 0) {\n      const [parent, i, html] = stack.at(-1);\n      if (i + 1 === parent.children.length) {\n        stack.pop();\n        continue;\n      }\n      const child = parent.children[++stack.at(-1)[1]];\n      if (child === null) {\n        continue;\n      }\n      const {\n        name\n      } = child;\n      if (name === \"#text\") {\n        const node = document.createTextNode(child.value);\n        textDivs.push(node);\n        html.append(node);\n        continue;\n      }\n      const childHtml = child?.attributes?.xmlns ? document.createElementNS(child.attributes.xmlns, name) : document.createElement(name);\n      html.append(childHtml);\n      if (child.attributes) {\n        this.setAttributes({\n          html: childHtml,\n          element: child,\n          storage,\n          intent,\n          linkService\n        });\n      }\n      if (child.children?.length > 0) {\n        stack.push([child, -1, childHtml]);\n      } else if (child.value) {\n        const node = document.createTextNode(child.value);\n        if (isNotForRichText && _xfa_text_js__WEBPACK_IMPORTED_MODULE_0__.XfaText.shouldBuildText(name)) {\n          textDivs.push(node);\n        }\n        childHtml.append(node);\n      }\n    }\n    for (const el of rootDiv.querySelectorAll(\".xfaNonInteractive input, .xfaNonInteractive textarea\")) {\n      el.setAttribute(\"readOnly\", true);\n    }\n    return {\n      textDivs\n    };\n  }\n  static update(parameters) {\n    const transform = `matrix(${parameters.viewport.transform.join(\",\")})`;\n    parameters.div.style.transform = transform;\n    parameters.div.hidden = false;\n  }\n}\n\n\n/***/ }),\n\n/***/ 292:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   AbortException: () => (/* binding */ AbortException),\n/* harmony export */   AnnotationBorderStyleType: () => (/* binding */ AnnotationBorderStyleType),\n/* harmony export */   AnnotationEditorParamsType: () => (/* binding */ AnnotationEditorParamsType),\n/* harmony export */   AnnotationEditorPrefix: () => (/* binding */ AnnotationEditorPrefix),\n/* harmony export */   AnnotationEditorType: () => (/* binding */ AnnotationEditorType),\n/* harmony export */   AnnotationMode: () => (/* binding */ AnnotationMode),\n/* harmony export */   AnnotationPrefix: () => (/* binding */ AnnotationPrefix),\n/* harmony export */   AnnotationType: () => (/* binding */ AnnotationType),\n/* harmony export */   BaseException: () => (/* binding */ BaseException),\n/* harmony export */   CMapCompressionType: () => (/* binding */ CMapCompressionType),\n/* harmony export */   FONT_IDENTITY_MATRIX: () => (/* binding */ FONT_IDENTITY_MATRIX),\n/* harmony export */   FeatureTest: () => (/* binding */ FeatureTest),\n/* harmony export */   FormatError: () => (/* binding */ FormatError),\n/* harmony export */   IDENTITY_MATRIX: () => (/* binding */ IDENTITY_MATRIX),\n/* harmony export */   ImageKind: () => (/* binding */ ImageKind),\n/* harmony export */   InvalidPDFException: () => (/* binding */ InvalidPDFException),\n/* harmony export */   LINE_FACTOR: () => (/* binding */ LINE_FACTOR),\n/* harmony export */   MAX_IMAGE_SIZE_TO_CACHE: () => (/* binding */ MAX_IMAGE_SIZE_TO_CACHE),\n/* harmony export */   MissingPDFException: () => (/* binding */ MissingPDFException),\n/* harmony export */   OPS: () => (/* binding */ OPS),\n/* harmony export */   PasswordException: () => (/* binding */ PasswordException),\n/* harmony export */   PasswordResponses: () => (/* binding */ PasswordResponses),\n/* harmony export */   PermissionFlag: () => (/* binding */ PermissionFlag),\n/* harmony export */   PromiseCapability: () => (/* binding */ PromiseCapability),\n/* harmony export */   RenderingIntentFlag: () => (/* binding */ RenderingIntentFlag),\n/* harmony export */   TextRenderingMode: () => (/* binding */ TextRenderingMode),\n/* harmony export */   UnexpectedResponseException: () => (/* binding */ UnexpectedResponseException),\n/* harmony export */   UnknownErrorException: () => (/* binding */ UnknownErrorException),\n/* harmony export */   Util: () => (/* binding */ Util),\n/* harmony export */   VerbosityLevel: () => (/* binding */ VerbosityLevel),\n/* harmony export */   assert: () => (/* binding */ assert),\n/* harmony export */   bytesToString: () => (/* binding */ bytesToString),\n/* harmony export */   createValidAbsoluteUrl: () => (/* binding */ createValidAbsoluteUrl),\n/* harmony export */   getUuid: () => (/* binding */ getUuid),\n/* harmony export */   getVerbosityLevel: () => (/* binding */ getVerbosityLevel),\n/* harmony export */   info: () => (/* binding */ info),\n/* harmony export */   isNodeJS: () => (/* binding */ isNodeJS),\n/* harmony export */   normalizeUnicode: () => (/* binding */ normalizeUnicode),\n/* harmony export */   objectFromMap: () => (/* binding */ objectFromMap),\n/* harmony export */   setVerbosityLevel: () => (/* binding */ setVerbosityLevel),\n/* harmony export */   shadow: () => (/* binding */ shadow),\n/* harmony export */   string32: () => (/* binding */ string32),\n/* harmony export */   stringToBytes: () => (/* binding */ stringToBytes),\n/* harmony export */   unreachable: () => (/* binding */ unreachable),\n/* harmony export */   warn: () => (/* binding */ warn)\n/* harmony export */ });\n/* unused harmony exports AnnotationActionEventType, AnnotationFieldFlag, AnnotationFlag, AnnotationReplyType, BASELINE_FACTOR, DocumentActionEventType, getModificationDate, isArrayEqual, LINE_DESCENT_FACTOR, objectSize, PageActionEventType, stringToPDFString, stringToUTF8String, utf8StringToString */\nconst isNodeJS = typeof process === \"object\" && process + \"\" === \"[object process]\" && !process.versions.nw && !(process.versions.electron && process.type && process.type !== \"browser\");\nconst IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];\nconst FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];\nconst MAX_IMAGE_SIZE_TO_CACHE = 10e6;\nconst LINE_FACTOR = 1.35;\nconst LINE_DESCENT_FACTOR = 0.35;\nconst BASELINE_FACTOR = LINE_DESCENT_FACTOR / LINE_FACTOR;\nconst RenderingIntentFlag = {\n  ANY: 0x01,\n  DISPLAY: 0x02,\n  PRINT: 0x04,\n  SAVE: 0x08,\n  ANNOTATIONS_FORMS: 0x10,\n  ANNOTATIONS_STORAGE: 0x20,\n  ANNOTATIONS_DISABLE: 0x40,\n  OPLIST: 0x100\n};\nconst AnnotationMode = {\n  DISABLE: 0,\n  ENABLE: 1,\n  ENABLE_FORMS: 2,\n  ENABLE_STORAGE: 3\n};\nconst AnnotationEditorPrefix = \"pdfjs_internal_editor_\";\nconst AnnotationEditorType = {\n  DISABLE: -1,\n  NONE: 0,\n  FREETEXT: 3,\n  HIGHLIGHT: 9,\n  STAMP: 13,\n  INK: 15\n};\nconst AnnotationEditorParamsType = {\n  RESIZE: 1,\n  CREATE: 2,\n  FREETEXT_SIZE: 11,\n  FREETEXT_COLOR: 12,\n  FREETEXT_OPACITY: 13,\n  INK_COLOR: 21,\n  INK_THICKNESS: 22,\n  INK_OPACITY: 23,\n  HIGHLIGHT_COLOR: 31,\n  HIGHLIGHT_DEFAULT_COLOR: 32,\n  HIGHLIGHT_THICKNESS: 33,\n  HIGHLIGHT_FREE: 34,\n  HIGHLIGHT_SHOW_ALL: 35\n};\nconst PermissionFlag = {\n  PRINT: 0x04,\n  MODIFY_CONTENTS: 0x08,\n  COPY: 0x10,\n  MODIFY_ANNOTATIONS: 0x20,\n  FILL_INTERACTIVE_FORMS: 0x100,\n  COPY_FOR_ACCESSIBILITY: 0x200,\n  ASSEMBLE: 0x400,\n  PRINT_HIGH_QUALITY: 0x800\n};\nconst TextRenderingMode = {\n  FILL: 0,\n  STROKE: 1,\n  FILL_STROKE: 2,\n  INVISIBLE: 3,\n  FILL_ADD_TO_PATH: 4,\n  STROKE_ADD_TO_PATH: 5,\n  FILL_STROKE_ADD_TO_PATH: 6,\n  ADD_TO_PATH: 7,\n  FILL_STROKE_MASK: 3,\n  ADD_TO_PATH_FLAG: 4\n};\nconst ImageKind = {\n  GRAYSCALE_1BPP: 1,\n  RGB_24BPP: 2,\n  RGBA_32BPP: 3\n};\nconst AnnotationType = {\n  TEXT: 1,\n  LINK: 2,\n  FREETEXT: 3,\n  LINE: 4,\n  SQUARE: 5,\n  CIRCLE: 6,\n  POLYGON: 7,\n  POLYLINE: 8,\n  HIGHLIGHT: 9,\n  UNDERLINE: 10,\n  SQUIGGLY: 11,\n  STRIKEOUT: 12,\n  STAMP: 13,\n  CARET: 14,\n  INK: 15,\n  POPUP: 16,\n  FILEATTACHMENT: 17,\n  SOUND: 18,\n  MOVIE: 19,\n  WIDGET: 20,\n  SCREEN: 21,\n  PRINTERMARK: 22,\n  TRAPNET: 23,\n  WATERMARK: 24,\n  THREED: 25,\n  REDACT: 26\n};\nconst AnnotationReplyType = {\n  GROUP: \"Group\",\n  REPLY: \"R\"\n};\nconst AnnotationFlag = {\n  INVISIBLE: 0x01,\n  HIDDEN: 0x02,\n  PRINT: 0x04,\n  NOZOOM: 0x08,\n  NOROTATE: 0x10,\n  NOVIEW: 0x20,\n  READONLY: 0x40,\n  LOCKED: 0x80,\n  TOGGLENOVIEW: 0x100,\n  LOCKEDCONTENTS: 0x200\n};\nconst AnnotationFieldFlag = {\n  READONLY: 0x0000001,\n  REQUIRED: 0x0000002,\n  NOEXPORT: 0x0000004,\n  MULTILINE: 0x0001000,\n  PASSWORD: 0x0002000,\n  NOTOGGLETOOFF: 0x0004000,\n  RADIO: 0x0008000,\n  PUSHBUTTON: 0x0010000,\n  COMBO: 0x0020000,\n  EDIT: 0x0040000,\n  SORT: 0x0080000,\n  FILESELECT: 0x0100000,\n  MULTISELECT: 0x0200000,\n  DONOTSPELLCHECK: 0x0400000,\n  DONOTSCROLL: 0x0800000,\n  COMB: 0x1000000,\n  RICHTEXT: 0x2000000,\n  RADIOSINUNISON: 0x2000000,\n  COMMITONSELCHANGE: 0x4000000\n};\nconst AnnotationBorderStyleType = {\n  SOLID: 1,\n  DASHED: 2,\n  BEVELED: 3,\n  INSET: 4,\n  UNDERLINE: 5\n};\nconst AnnotationActionEventType = {\n  E: \"Mouse Enter\",\n  X: \"Mouse Exit\",\n  D: \"Mouse Down\",\n  U: \"Mouse Up\",\n  Fo: \"Focus\",\n  Bl: \"Blur\",\n  PO: \"PageOpen\",\n  PC: \"PageClose\",\n  PV: \"PageVisible\",\n  PI: \"PageInvisible\",\n  K: \"Keystroke\",\n  F: \"Format\",\n  V: \"Validate\",\n  C: \"Calculate\"\n};\nconst DocumentActionEventType = {\n  WC: \"WillClose\",\n  WS: \"WillSave\",\n  DS: \"DidSave\",\n  WP: \"WillPrint\",\n  DP: \"DidPrint\"\n};\nconst PageActionEventType = {\n  O: \"PageOpen\",\n  C: \"PageClose\"\n};\nconst VerbosityLevel = {\n  ERRORS: 0,\n  WARNINGS: 1,\n  INFOS: 5\n};\nconst CMapCompressionType = {\n  NONE: 0,\n  BINARY: 1\n};\nconst OPS = {\n  dependency: 1,\n  setLineWidth: 2,\n  setLineCap: 3,\n  setLineJoin: 4,\n  setMiterLimit: 5,\n  setDash: 6,\n  setRenderingIntent: 7,\n  setFlatness: 8,\n  setGState: 9,\n  save: 10,\n  restore: 11,\n  transform: 12,\n  moveTo: 13,\n  lineTo: 14,\n  curveTo: 15,\n  curveTo2: 16,\n  curveTo3: 17,\n  closePath: 18,\n  rectangle: 19,\n  stroke: 20,\n  closeStroke: 21,\n  fill: 22,\n  eoFill: 23,\n  fillStroke: 24,\n  eoFillStroke: 25,\n  closeFillStroke: 26,\n  closeEOFillStroke: 27,\n  endPath: 28,\n  clip: 29,\n  eoClip: 30,\n  beginText: 31,\n  endText: 32,\n  setCharSpacing: 33,\n  setWordSpacing: 34,\n  setHScale: 35,\n  setLeading: 36,\n  setFont: 37,\n  setTextRenderingMode: 38,\n  setTextRise: 39,\n  moveText: 40,\n  setLeadingMoveText: 41,\n  setTextMatrix: 42,\n  nextLine: 43,\n  showText: 44,\n  showSpacedText: 45,\n  nextLineShowText: 46,\n  nextLineSetSpacingShowText: 47,\n  setCharWidth: 48,\n  setCharWidthAndBounds: 49,\n  setStrokeColorSpace: 50,\n  setFillColorSpace: 51,\n  setStrokeColor: 52,\n  setStrokeColorN: 53,\n  setFillColor: 54,\n  setFillColorN: 55,\n  setStrokeGray: 56,\n  setFillGray: 57,\n  setStrokeRGBColor: 58,\n  setFillRGBColor: 59,\n  setStrokeCMYKColor: 60,\n  setFillCMYKColor: 61,\n  shadingFill: 62,\n  beginInlineImage: 63,\n  beginImageData: 64,\n  endInlineImage: 65,\n  paintXObject: 66,\n  markPoint: 67,\n  markPointProps: 68,\n  beginMarkedContent: 69,\n  beginMarkedContentProps: 70,\n  endMarkedContent: 71,\n  beginCompat: 72,\n  endCompat: 73,\n  paintFormXObjectBegin: 74,\n  paintFormXObjectEnd: 75,\n  beginGroup: 76,\n  endGroup: 77,\n  beginAnnotation: 80,\n  endAnnotation: 81,\n  paintImageMaskXObject: 83,\n  paintImageMaskXObjectGroup: 84,\n  paintImageXObject: 85,\n  paintInlineImageXObject: 86,\n  paintInlineImageXObjectGroup: 87,\n  paintImageXObjectRepeat: 88,\n  paintImageMaskXObjectRepeat: 89,\n  paintSolidColorImageMask: 90,\n  constructPath: 91\n};\nconst PasswordResponses = {\n  NEED_PASSWORD: 1,\n  INCORRECT_PASSWORD: 2\n};\nlet verbosity = VerbosityLevel.WARNINGS;\nfunction setVerbosityLevel(level) {\n  if (Number.isInteger(level)) {\n    verbosity = level;\n  }\n}\nfunction getVerbosityLevel() {\n  return verbosity;\n}\nfunction info(msg) {\n  if (verbosity >= VerbosityLevel.INFOS) {\n    console.error(`Info: ${msg}`);\n  }\n}\nfunction warn(msg) {\n  if (verbosity >= VerbosityLevel.WARNINGS) {\n    console.error(`Warning: ${msg}`);\n  }\n}\nfunction unreachable(msg) {\n  throw new Error(msg);\n}\nfunction assert(cond, msg) {\n  if (!cond) {\n    unreachable(msg);\n  }\n}\nfunction _isValidProtocol(url) {\n  switch (url?.protocol) {\n    case \"http:\":\n    case \"https:\":\n    case \"ftp:\":\n    case \"mailto:\":\n    case \"tel:\":\n      return true;\n    default:\n      return false;\n  }\n}\nfunction createValidAbsoluteUrl(url, baseUrl = null, options = null) {\n  if (!url) {\n    return null;\n  }\n  try {\n    if (options && typeof url === \"string\") {\n      if (options.addDefaultProtocol && url.startsWith(\"www.\")) {\n        const dots = url.match(/\\./g);\n        if (dots?.length >= 2) {\n          url = `http://${url}`;\n        }\n      }\n      if (options.tryConvertEncoding) {\n        try {\n          url = stringToUTF8String(url);\n        } catch {}\n      }\n    }\n    const absoluteUrl = baseUrl ? new URL(url, baseUrl) : new URL(url);\n    if (_isValidProtocol(absoluteUrl)) {\n      return absoluteUrl;\n    }\n  } catch {}\n  return null;\n}\nfunction shadow(obj, prop, value, nonSerializable = false) {\n  Object.defineProperty(obj, prop, {\n    value,\n    enumerable: !nonSerializable,\n    configurable: true,\n    writable: false\n  });\n  return value;\n}\nconst BaseException = function BaseExceptionClosure() {\n  function BaseException(message, name) {\n    if (this.constructor === BaseException) {\n      unreachable(\"Cannot initialize BaseException.\");\n    }\n    this.message = message;\n    this.name = name;\n  }\n  BaseException.prototype = new Error();\n  BaseException.constructor = BaseException;\n  return BaseException;\n}();\nclass PasswordException extends BaseException {\n  constructor(msg, code) {\n    super(msg, \"PasswordException\");\n    this.code = code;\n  }\n}\nclass UnknownErrorException extends BaseException {\n  constructor(msg, details) {\n    super(msg, \"UnknownErrorException\");\n    this.details = details;\n  }\n}\nclass InvalidPDFException extends BaseException {\n  constructor(msg) {\n    super(msg, \"InvalidPDFException\");\n  }\n}\nclass MissingPDFException extends BaseException {\n  constructor(msg) {\n    super(msg, \"MissingPDFException\");\n  }\n}\nclass UnexpectedResponseException extends BaseException {\n  constructor(msg, status) {\n    super(msg, \"UnexpectedResponseException\");\n    this.status = status;\n  }\n}\nclass FormatError extends BaseException {\n  constructor(msg) {\n    super(msg, \"FormatError\");\n  }\n}\nclass AbortException extends BaseException {\n  constructor(msg) {\n    super(msg, \"AbortException\");\n  }\n}\nfunction bytesToString(bytes) {\n  if (typeof bytes !== \"object\" || bytes?.length === undefined) {\n    unreachable(\"Invalid argument for bytesToString\");\n  }\n  const length = bytes.length;\n  const MAX_ARGUMENT_COUNT = 8192;\n  if (length < MAX_ARGUMENT_COUNT) {\n    return String.fromCharCode.apply(null, bytes);\n  }\n  const strBuf = [];\n  for (let i = 0; i < length; i += MAX_ARGUMENT_COUNT) {\n    const chunkEnd = Math.min(i + MAX_ARGUMENT_COUNT, length);\n    const chunk = bytes.subarray(i, chunkEnd);\n    strBuf.push(String.fromCharCode.apply(null, chunk));\n  }\n  return strBuf.join(\"\");\n}\nfunction stringToBytes(str) {\n  if (typeof str !== \"string\") {\n    unreachable(\"Invalid argument for stringToBytes\");\n  }\n  const length = str.length;\n  const bytes = new Uint8Array(length);\n  for (let i = 0; i < length; ++i) {\n    bytes[i] = str.charCodeAt(i) & 0xff;\n  }\n  return bytes;\n}\nfunction string32(value) {\n  return String.fromCharCode(value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff);\n}\nfunction objectSize(obj) {\n  return Object.keys(obj).length;\n}\nfunction objectFromMap(map) {\n  const obj = Object.create(null);\n  for (const [key, value] of map) {\n    obj[key] = value;\n  }\n  return obj;\n}\nfunction isLittleEndian() {\n  const buffer8 = new Uint8Array(4);\n  buffer8[0] = 1;\n  const view32 = new Uint32Array(buffer8.buffer, 0, 1);\n  return view32[0] === 1;\n}\nfunction isEvalSupported() {\n  try {\n    new Function(\"\");\n    return true;\n  } catch {\n    return false;\n  }\n}\nclass FeatureTest {\n  static get isLittleEndian() {\n    return shadow(this, \"isLittleEndian\", isLittleEndian());\n  }\n  static get isEvalSupported() {\n    return shadow(this, \"isEvalSupported\", isEvalSupported());\n  }\n  static get isOffscreenCanvasSupported() {\n    return shadow(this, \"isOffscreenCanvasSupported\", typeof OffscreenCanvas !== \"undefined\");\n  }\n  static get platform() {\n    if (typeof navigator !== \"undefined\" && typeof navigator?.platform === \"string\") {\n      return shadow(this, \"platform\", {\n        isMac: navigator.platform.includes(\"Mac\")\n      });\n    }\n    return shadow(this, \"platform\", {\n      isMac: false\n    });\n  }\n  static get isCSSRoundSupported() {\n    return shadow(this, \"isCSSRoundSupported\", globalThis.CSS?.supports?.(\"width: round(1.5px, 1px)\"));\n  }\n}\nconst hexNumbers = Array.from(Array(256).keys(), n => n.toString(16).padStart(2, \"0\"));\nclass Util {\n  static makeHexColor(r, g, b) {\n    return `#${hexNumbers[r]}${hexNumbers[g]}${hexNumbers[b]}`;\n  }\n  static scaleMinMax(transform, minMax) {\n    let temp;\n    if (transform[0]) {\n      if (transform[0] < 0) {\n        temp = minMax[0];\n        minMax[0] = minMax[2];\n        minMax[2] = temp;\n      }\n      minMax[0] *= transform[0];\n      minMax[2] *= transform[0];\n      if (transform[3] < 0) {\n        temp = minMax[1];\n        minMax[1] = minMax[3];\n        minMax[3] = temp;\n      }\n      minMax[1] *= transform[3];\n      minMax[3] *= transform[3];\n    } else {\n      temp = minMax[0];\n      minMax[0] = minMax[1];\n      minMax[1] = temp;\n      temp = minMax[2];\n      minMax[2] = minMax[3];\n      minMax[3] = temp;\n      if (transform[1] < 0) {\n        temp = minMax[1];\n        minMax[1] = minMax[3];\n        minMax[3] = temp;\n      }\n      minMax[1] *= transform[1];\n      minMax[3] *= transform[1];\n      if (transform[2] < 0) {\n        temp = minMax[0];\n        minMax[0] = minMax[2];\n        minMax[2] = temp;\n      }\n      minMax[0] *= transform[2];\n      minMax[2] *= transform[2];\n    }\n    minMax[0] += transform[4];\n    minMax[1] += transform[5];\n    minMax[2] += transform[4];\n    minMax[3] += transform[5];\n  }\n  static transform(m1, m2) {\n    return [m1[0] * m2[0] + m1[2] * m2[1], m1[1] * m2[0] + m1[3] * m2[1], m1[0] * m2[2] + m1[2] * m2[3], m1[1] * m2[2] + m1[3] * m2[3], m1[0] * m2[4] + m1[2] * m2[5] + m1[4], m1[1] * m2[4] + m1[3] * m2[5] + m1[5]];\n  }\n  static applyTransform(p, m) {\n    const xt = p[0] * m[0] + p[1] * m[2] + m[4];\n    const yt = p[0] * m[1] + p[1] * m[3] + m[5];\n    return [xt, yt];\n  }\n  static applyInverseTransform(p, m) {\n    const d = m[0] * m[3] - m[1] * m[2];\n    const xt = (p[0] * m[3] - p[1] * m[2] + m[2] * m[5] - m[4] * m[3]) / d;\n    const yt = (-p[0] * m[1] + p[1] * m[0] + m[4] * m[1] - m[5] * m[0]) / d;\n    return [xt, yt];\n  }\n  static getAxialAlignedBoundingBox(r, m) {\n    const p1 = this.applyTransform(r, m);\n    const p2 = this.applyTransform(r.slice(2, 4), m);\n    const p3 = this.applyTransform([r[0], r[3]], m);\n    const p4 = this.applyTransform([r[2], r[1]], m);\n    return [Math.min(p1[0], p2[0], p3[0], p4[0]), Math.min(p1[1], p2[1], p3[1], p4[1]), Math.max(p1[0], p2[0], p3[0], p4[0]), Math.max(p1[1], p2[1], p3[1], p4[1])];\n  }\n  static inverseTransform(m) {\n    const d = m[0] * m[3] - m[1] * m[2];\n    return [m[3] / d, -m[1] / d, -m[2] / d, m[0] / d, (m[2] * m[5] - m[4] * m[3]) / d, (m[4] * m[1] - m[5] * m[0]) / d];\n  }\n  static getRotation(m) {\n    return Math.atan2(m[1], m[0]) * (180 / Math.PI);\n  }\n  static singularValueDecompose2dScale(m) {\n    const transpose = [m[0], m[2], m[1], m[3]];\n    const a = m[0] * transpose[0] + m[1] * transpose[2];\n    const b = m[0] * transpose[1] + m[1] * transpose[3];\n    const c = m[2] * transpose[0] + m[3] * transpose[2];\n    const d = m[2] * transpose[1] + m[3] * transpose[3];\n    const first = (a + d) / 2;\n    const second = Math.sqrt((a + d) ** 2 - 4 * (a * d - c * b)) / 2;\n    const sx = first + second || 1;\n    const sy = first - second || 1;\n    return [Math.sqrt(sx), Math.sqrt(sy)];\n  }\n  static normalizeRect(rect) {\n    const r = rect.slice(0);\n    if (rect[0] > rect[2]) {\n      r[0] = rect[2];\n      r[2] = rect[0];\n    }\n    if (rect[1] > rect[3]) {\n      r[1] = rect[3];\n      r[3] = rect[1];\n    }\n    return r;\n  }\n  static intersect(rect1, rect2) {\n    const xLow = Math.max(Math.min(rect1[0], rect1[2]), Math.min(rect2[0], rect2[2]));\n    const xHigh = Math.min(Math.max(rect1[0], rect1[2]), Math.max(rect2[0], rect2[2]));\n    if (xLow > xHigh) {\n      return null;\n    }\n    const yLow = Math.max(Math.min(rect1[1], rect1[3]), Math.min(rect2[1], rect2[3]));\n    const yHigh = Math.min(Math.max(rect1[1], rect1[3]), Math.max(rect2[1], rect2[3]));\n    if (yLow > yHigh) {\n      return null;\n    }\n    return [xLow, yLow, xHigh, yHigh];\n  }\n  static #getExtremumOnCurve(x0, x1, x2, x3, y0, y1, y2, y3, t, minMax) {\n    if (t <= 0 || t >= 1) {\n      return;\n    }\n    const mt = 1 - t;\n    const tt = t * t;\n    const ttt = tt * t;\n    const x = mt * (mt * (mt * x0 + 3 * t * x1) + 3 * tt * x2) + ttt * x3;\n    const y = mt * (mt * (mt * y0 + 3 * t * y1) + 3 * tt * y2) + ttt * y3;\n    minMax[0] = Math.min(minMax[0], x);\n    minMax[1] = Math.min(minMax[1], y);\n    minMax[2] = Math.max(minMax[2], x);\n    minMax[3] = Math.max(minMax[3], y);\n  }\n  static #getExtremum(x0, x1, x2, x3, y0, y1, y2, y3, a, b, c, minMax) {\n    if (Math.abs(a) < 1e-12) {\n      if (Math.abs(b) >= 1e-12) {\n        this.#getExtremumOnCurve(x0, x1, x2, x3, y0, y1, y2, y3, -c / b, minMax);\n      }\n      return;\n    }\n    const delta = b ** 2 - 4 * c * a;\n    if (delta < 0) {\n      return;\n    }\n    const sqrtDelta = Math.sqrt(delta);\n    const a2 = 2 * a;\n    this.#getExtremumOnCurve(x0, x1, x2, x3, y0, y1, y2, y3, (-b + sqrtDelta) / a2, minMax);\n    this.#getExtremumOnCurve(x0, x1, x2, x3, y0, y1, y2, y3, (-b - sqrtDelta) / a2, minMax);\n  }\n  static bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3, minMax) {\n    if (minMax) {\n      minMax[0] = Math.min(minMax[0], x0, x3);\n      minMax[1] = Math.min(minMax[1], y0, y3);\n      minMax[2] = Math.max(minMax[2], x0, x3);\n      minMax[3] = Math.max(minMax[3], y0, y3);\n    } else {\n      minMax = [Math.min(x0, x3), Math.min(y0, y3), Math.max(x0, x3), Math.max(y0, y3)];\n    }\n    this.#getExtremum(x0, x1, x2, x3, y0, y1, y2, y3, 3 * (-x0 + 3 * (x1 - x2) + x3), 6 * (x0 - 2 * x1 + x2), 3 * (x1 - x0), minMax);\n    this.#getExtremum(x0, x1, x2, x3, y0, y1, y2, y3, 3 * (-y0 + 3 * (y1 - y2) + y3), 6 * (y0 - 2 * y1 + y2), 3 * (y1 - y0), minMax);\n    return minMax;\n  }\n}\nconst PDFStringTranslateTable = (/* unused pure expression or super */ null && ([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2d8, 0x2c7, 0x2c6, 0x2d9, 0x2dd, 0x2db, 0x2da, 0x2dc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x192, 0x2044, 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018, 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x141, 0x152, 0x160, 0x178, 0x17d, 0x131, 0x142, 0x153, 0x161, 0x17e, 0, 0x20ac]));\nfunction stringToPDFString(str) {\n  if (str[0] >= \"\\xEF\") {\n    let encoding;\n    if (str[0] === \"\\xFE\" && str[1] === \"\\xFF\") {\n      encoding = \"utf-16be\";\n      if (str.length % 2 === 1) {\n        str = str.slice(0, -1);\n      }\n    } else if (str[0] === \"\\xFF\" && str[1] === \"\\xFE\") {\n      encoding = \"utf-16le\";\n      if (str.length % 2 === 1) {\n        str = str.slice(0, -1);\n      }\n    } else if (str[0] === \"\\xEF\" && str[1] === \"\\xBB\" && str[2] === \"\\xBF\") {\n      encoding = \"utf-8\";\n    }\n    if (encoding) {\n      try {\n        const decoder = new TextDecoder(encoding, {\n          fatal: true\n        });\n        const buffer = stringToBytes(str);\n        const decoded = decoder.decode(buffer);\n        if (!decoded.includes(\"\\x1b\")) {\n          return decoded;\n        }\n        return decoded.replaceAll(/\\x1b[^\\x1b]*(?:\\x1b|$)/g, \"\");\n      } catch (ex) {\n        warn(`stringToPDFString: \"${ex}\".`);\n      }\n    }\n  }\n  const strBuf = [];\n  for (let i = 0, ii = str.length; i < ii; i++) {\n    const charCode = str.charCodeAt(i);\n    if (charCode === 0x1b) {\n      while (++i < ii && str.charCodeAt(i) !== 0x1b) {}\n      continue;\n    }\n    const code = PDFStringTranslateTable[charCode];\n    strBuf.push(code ? String.fromCharCode(code) : str.charAt(i));\n  }\n  return strBuf.join(\"\");\n}\nfunction stringToUTF8String(str) {\n  return decodeURIComponent(escape(str));\n}\nfunction utf8StringToString(str) {\n  return unescape(encodeURIComponent(str));\n}\nfunction isArrayEqual(arr1, arr2) {\n  if (arr1.length !== arr2.length) {\n    return false;\n  }\n  for (let i = 0, ii = arr1.length; i < ii; i++) {\n    if (arr1[i] !== arr2[i]) {\n      return false;\n    }\n  }\n  return true;\n}\nfunction getModificationDate(date = new Date()) {\n  const buffer = [date.getUTCFullYear().toString(), (date.getUTCMonth() + 1).toString().padStart(2, \"0\"), date.getUTCDate().toString().padStart(2, \"0\"), date.getUTCHours().toString().padStart(2, \"0\"), date.getUTCMinutes().toString().padStart(2, \"0\"), date.getUTCSeconds().toString().padStart(2, \"0\")];\n  return buffer.join(\"\");\n}\nclass PromiseCapability {\n  #settled = false;\n  constructor() {\n    this.promise = new Promise((resolve, reject) => {\n      this.resolve = data => {\n        this.#settled = true;\n        resolve(data);\n      };\n      this.reject = reason => {\n        this.#settled = true;\n        reject(reason);\n      };\n    });\n  }\n  get settled() {\n    return this.#settled;\n  }\n}\nlet NormalizeRegex = null;\nlet NormalizationMap = null;\nfunction normalizeUnicode(str) {\n  if (!NormalizeRegex) {\n    NormalizeRegex = /([\\u00a0\\u00b5\\u037e\\u0eb3\\u2000-\\u200a\\u202f\\u2126\\ufb00-\\ufb04\\ufb06\\ufb20-\\ufb36\\ufb38-\\ufb3c\\ufb3e\\ufb40-\\ufb41\\ufb43-\\ufb44\\ufb46-\\ufba1\\ufba4-\\ufba9\\ufbae-\\ufbb1\\ufbd3-\\ufbdc\\ufbde-\\ufbe7\\ufbea-\\ufbf8\\ufbfc-\\ufbfd\\ufc00-\\ufc5d\\ufc64-\\ufcf1\\ufcf5-\\ufd3d\\ufd88\\ufdf4\\ufdfa-\\ufdfb\\ufe71\\ufe77\\ufe79\\ufe7b\\ufe7d]+)|(\\ufb05+)/gu;\n    NormalizationMap = new Map([[\"ﬅ\", \"ſt\"]]);\n  }\n  return str.replaceAll(NormalizeRegex, (_, p1, p2) => p1 ? p1.normalize(\"NFKC\") : NormalizationMap.get(p2));\n}\nfunction getUuid() {\n  if (typeof crypto !== \"undefined\" && typeof crypto?.randomUUID === \"function\") {\n    return crypto.randomUUID();\n  }\n  const buf = new Uint8Array(32);\n  if (typeof crypto !== \"undefined\" && typeof crypto?.getRandomValues === \"function\") {\n    crypto.getRandomValues(buf);\n  } else {\n    for (let i = 0; i < 32; i++) {\n      buf[i] = Math.floor(Math.random() * 255);\n    }\n  }\n  return bytesToString(buf);\n}\nconst AnnotationPrefix = \"pdfjs_internal_id_\";\n\n\n/***/ }),\n\n/***/ 310:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n  AnnotationEditor: () => (/* binding */ AnnotationEditor)\n});\n\n// EXTERNAL MODULE: ./src/display/editor/tools.js\nvar tools = __webpack_require__(830);\n// EXTERNAL MODULE: ./src/shared/util.js\nvar util = __webpack_require__(292);\n// EXTERNAL MODULE: ./src/display/display_utils.js\nvar display_utils = __webpack_require__(419);\n;// ./src/display/editor/alt_text.js\n\nclass AltText {\n  #altText = \"\";\n  #altTextDecorative = false;\n  #altTextButton = null;\n  #altTextTooltip = null;\n  #altTextTooltipTimeout = null;\n  #altTextWasFromKeyBoard = false;\n  #editor = null;\n  static _l10nPromise = null;\n  constructor(editor) {\n    this.#editor = editor;\n  }\n  static initialize(l10nPromise) {\n    AltText._l10nPromise ||= l10nPromise;\n  }\n  async render() {\n    const altText = this.#altTextButton = document.createElement(\"button\");\n    altText.className = \"altText\";\n    const msg = await AltText._l10nPromise.get(\"pdfjs-editor-alt-text-button-label\");\n    altText.textContent = msg;\n    altText.setAttribute(\"aria-label\", msg);\n    altText.tabIndex = \"0\";\n    altText.addEventListener(\"contextmenu\", display_utils.noContextMenu);\n    altText.addEventListener(\"pointerdown\", event => event.stopPropagation());\n    const onClick = event => {\n      event.preventDefault();\n      this.#editor._uiManager.editAltText(this.#editor);\n    };\n    altText.addEventListener(\"click\", onClick, {\n      capture: true\n    });\n    altText.addEventListener(\"keydown\", event => {\n      if (event.target === altText && event.key === \"Enter\") {\n        this.#altTextWasFromKeyBoard = true;\n        onClick(event);\n      }\n    });\n    await this.#setState();\n    return altText;\n  }\n  finish() {\n    if (!this.#altTextButton) {\n      return;\n    }\n    this.#altTextButton.focus({\n      focusVisible: this.#altTextWasFromKeyBoard\n    });\n    this.#altTextWasFromKeyBoard = false;\n  }\n  isEmpty() {\n    return !this.#altText && !this.#altTextDecorative;\n  }\n  get data() {\n    return {\n      altText: this.#altText,\n      decorative: this.#altTextDecorative\n    };\n  }\n  set data({\n    altText,\n    decorative\n  }) {\n    if (this.#altText === altText && this.#altTextDecorative === decorative) {\n      return;\n    }\n    this.#altText = altText;\n    this.#altTextDecorative = decorative;\n    this.#setState();\n  }\n  toggle(enabled = false) {\n    if (!this.#altTextButton) {\n      return;\n    }\n    if (!enabled && this.#altTextTooltipTimeout) {\n      clearTimeout(this.#altTextTooltipTimeout);\n      this.#altTextTooltipTimeout = null;\n    }\n    this.#altTextButton.disabled = !enabled;\n  }\n  destroy() {\n    this.#altTextButton?.remove();\n    this.#altTextButton = null;\n    this.#altTextTooltip = null;\n  }\n  async #setState() {\n    const button = this.#altTextButton;\n    if (!button) {\n      return;\n    }\n    if (!this.#altText && !this.#altTextDecorative) {\n      button.classList.remove(\"done\");\n      this.#altTextTooltip?.remove();\n      return;\n    }\n    button.classList.add(\"done\");\n    AltText._l10nPromise.get(\"pdfjs-editor-alt-text-edit-button-label\").then(msg => {\n      button.setAttribute(\"aria-label\", msg);\n    });\n    let tooltip = this.#altTextTooltip;\n    if (!tooltip) {\n      this.#altTextTooltip = tooltip = document.createElement(\"span\");\n      tooltip.className = \"tooltip\";\n      tooltip.setAttribute(\"role\", \"tooltip\");\n      const id = tooltip.id = `alt-text-tooltip-${this.#editor.id}`;\n      button.setAttribute(\"aria-describedby\", id);\n      const DELAY_TO_SHOW_TOOLTIP = 100;\n      button.addEventListener(\"mouseenter\", () => {\n        this.#altTextTooltipTimeout = setTimeout(() => {\n          this.#altTextTooltipTimeout = null;\n          this.#altTextTooltip.classList.add(\"show\");\n          this.#editor._reportTelemetry({\n            action: \"alt_text_tooltip\"\n          });\n        }, DELAY_TO_SHOW_TOOLTIP);\n      });\n      button.addEventListener(\"mouseleave\", () => {\n        if (this.#altTextTooltipTimeout) {\n          clearTimeout(this.#altTextTooltipTimeout);\n          this.#altTextTooltipTimeout = null;\n        }\n        this.#altTextTooltip?.classList.remove(\"show\");\n      });\n    }\n    tooltip.innerText = this.#altTextDecorative ? await AltText._l10nPromise.get(\"pdfjs-editor-alt-text-decorative-tooltip\") : this.#altText;\n    if (!tooltip.parentNode) {\n      button.append(tooltip);\n    }\n    const element = this.#editor.getImageForAltText();\n    element?.setAttribute(\"aria-describedby\", tooltip.id);\n  }\n}\n\n// EXTERNAL MODULE: ./src/display/editor/toolbar.js\nvar toolbar = __webpack_require__(362);\n;// ./src/display/editor/editor.js\n\n\n\n\n\nclass AnnotationEditor {\n  #allResizerDivs = null;\n  #altText = null;\n  #keepAspectRatio = false;\n  #resizersDiv = null;\n  #savedDimensions = null;\n  #boundFocusin = this.focusin.bind(this);\n  #boundFocusout = this.focusout.bind(this);\n  #editToolbar = null;\n  #focusedResizerName = \"\";\n  #hasBeenClicked = false;\n  #isEditing = false;\n  #isInEditMode = false;\n  #isResizerEnabledForKeyboard = false;\n  #moveInDOMTimeout = null;\n  #prevDragX = 0;\n  #prevDragY = 0;\n  #telemetryTimeouts = null;\n  _initialOptions = Object.create(null);\n  _isVisible = true;\n  _uiManager = null;\n  _focusEventsAllowed = true;\n  _l10nPromise = null;\n  #isDraggable = false;\n  #zIndex = AnnotationEditor._zIndex++;\n  static _borderLineWidth = -1;\n  static _colorManager = new tools.ColorManager();\n  static _zIndex = 1;\n  static _telemetryTimeout = 1000;\n  static get _resizerKeyboardManager() {\n    const resize = AnnotationEditor.prototype._resizeWithKeyboard;\n    const small = tools.AnnotationEditorUIManager.TRANSLATE_SMALL;\n    const big = tools.AnnotationEditorUIManager.TRANSLATE_BIG;\n    return (0,util.shadow)(this, \"_resizerKeyboardManager\", new tools.KeyboardManager([[[\"ArrowLeft\", \"mac+ArrowLeft\"], resize, {\n      args: [-small, 0]\n    }], [[\"ctrl+ArrowLeft\", \"mac+shift+ArrowLeft\"], resize, {\n      args: [-big, 0]\n    }], [[\"ArrowRight\", \"mac+ArrowRight\"], resize, {\n      args: [small, 0]\n    }], [[\"ctrl+ArrowRight\", \"mac+shift+ArrowRight\"], resize, {\n      args: [big, 0]\n    }], [[\"ArrowUp\", \"mac+ArrowUp\"], resize, {\n      args: [0, -small]\n    }], [[\"ctrl+ArrowUp\", \"mac+shift+ArrowUp\"], resize, {\n      args: [0, -big]\n    }], [[\"ArrowDown\", \"mac+ArrowDown\"], resize, {\n      args: [0, small]\n    }], [[\"ctrl+ArrowDown\", \"mac+shift+ArrowDown\"], resize, {\n      args: [0, big]\n    }], [[\"Escape\", \"mac+Escape\"], AnnotationEditor.prototype._stopResizingWithKeyboard]]));\n  }\n  constructor(parameters) {\n    if (this.constructor === AnnotationEditor) {\n      (0,util.unreachable)(\"Cannot initialize AnnotationEditor.\");\n    }\n    this.parent = parameters.parent;\n    this.id = parameters.id;\n    this.width = this.height = null;\n    this.pageIndex = parameters.parent.pageIndex;\n    this.name = parameters.name;\n    this.div = null;\n    this._uiManager = parameters.uiManager;\n    this.annotationElementId = null;\n    this._willKeepAspectRatio = false;\n    this._initialOptions.isCentered = parameters.isCentered;\n    this._structTreeParentId = null;\n    const {\n      rotation,\n      rawDims: {\n        pageWidth,\n        pageHeight,\n        pageX,\n        pageY\n      }\n    } = this.parent.viewport;\n    this.rotation = rotation;\n    this.pageRotation = (360 + rotation - this._uiManager.viewParameters.rotation) % 360;\n    this.pageDimensions = [pageWidth, pageHeight];\n    this.pageTranslation = [pageX, pageY];\n    const [width, height] = this.parentDimensions;\n    this.x = parameters.x / width;\n    this.y = parameters.y / height;\n    this.isAttachedToDOM = false;\n    this.deleted = false;\n  }\n  get editorType() {\n    return Object.getPrototypeOf(this).constructor._type;\n  }\n  static get _defaultLineColor() {\n    return (0,util.shadow)(this, \"_defaultLineColor\", this._colorManager.getHexCode(\"CanvasText\"));\n  }\n  static deleteAnnotationElement(editor) {\n    const fakeEditor = new FakeEditor({\n      id: editor.parent.getNextId(),\n      parent: editor.parent,\n      uiManager: editor._uiManager\n    });\n    fakeEditor.annotationElementId = editor.annotationElementId;\n    fakeEditor.deleted = true;\n    fakeEditor._uiManager.addToAnnotationStorage(fakeEditor);\n  }\n  static initialize(l10n, _uiManager, options) {\n    AnnotationEditor._l10nPromise ||= new Map([\"pdfjs-editor-alt-text-button-label\", \"pdfjs-editor-alt-text-edit-button-label\", \"pdfjs-editor-alt-text-decorative-tooltip\", \"pdfjs-editor-resizer-label-topLeft\", \"pdfjs-editor-resizer-label-topMiddle\", \"pdfjs-editor-resizer-label-topRight\", \"pdfjs-editor-resizer-label-middleRight\", \"pdfjs-editor-resizer-label-bottomRight\", \"pdfjs-editor-resizer-label-bottomMiddle\", \"pdfjs-editor-resizer-label-bottomLeft\", \"pdfjs-editor-resizer-label-middleLeft\"].map(str => [str, l10n.get(str.replaceAll(/([A-Z])/g, c => `-${c.toLowerCase()}`))]));\n    if (options?.strings) {\n      for (const str of options.strings) {\n        AnnotationEditor._l10nPromise.set(str, l10n.get(str));\n      }\n    }\n    if (AnnotationEditor._borderLineWidth !== -1) {\n      return;\n    }\n    const style = getComputedStyle(document.documentElement);\n    AnnotationEditor._borderLineWidth = parseFloat(style.getPropertyValue(\"--outline-width\")) || 0;\n  }\n  static updateDefaultParams(_type, _value) {}\n  static get defaultPropertiesToUpdate() {\n    return [];\n  }\n  static isHandlingMimeForPasting(mime) {\n    return false;\n  }\n  static paste(item, parent) {\n    (0,util.unreachable)(\"Not implemented\");\n  }\n  get propertiesToUpdate() {\n    return [];\n  }\n  get _isDraggable() {\n    return this.#isDraggable;\n  }\n  set _isDraggable(value) {\n    this.#isDraggable = value;\n    this.div?.classList.toggle(\"draggable\", value);\n  }\n  get isEnterHandled() {\n    return true;\n  }\n  center() {\n    const [pageWidth, pageHeight] = this.pageDimensions;\n    switch (this.parentRotation) {\n      case 90:\n        this.x -= this.height * pageHeight / (pageWidth * 2);\n        this.y += this.width * pageWidth / (pageHeight * 2);\n        break;\n      case 180:\n        this.x += this.width / 2;\n        this.y += this.height / 2;\n        break;\n      case 270:\n        this.x += this.height * pageHeight / (pageWidth * 2);\n        this.y -= this.width * pageWidth / (pageHeight * 2);\n        break;\n      default:\n        this.x -= this.width / 2;\n        this.y -= this.height / 2;\n        break;\n    }\n    this.fixAndSetPosition();\n  }\n  addCommands(params) {\n    this._uiManager.addCommands(params);\n  }\n  get currentLayer() {\n    return this._uiManager.currentLayer;\n  }\n  setInBackground() {\n    this.div.style.zIndex = 0;\n  }\n  setInForeground() {\n    this.div.style.zIndex = this.#zIndex;\n  }\n  setParent(parent) {\n    if (parent !== null) {\n      this.pageIndex = parent.pageIndex;\n      this.pageDimensions = parent.pageDimensions;\n    } else {\n      this.#stopResizing();\n    }\n    this.parent = parent;\n  }\n  focusin(event) {\n    if (!this._focusEventsAllowed) {\n      return;\n    }\n    if (!this.#hasBeenClicked) {\n      this.parent.setSelected(this);\n    } else {\n      this.#hasBeenClicked = false;\n    }\n  }\n  focusout(event) {\n    if (!this._focusEventsAllowed) {\n      return;\n    }\n    if (!this.isAttachedToDOM) {\n      return;\n    }\n    const target = event.relatedTarget;\n    if (target?.closest(`#${this.id}`)) {\n      return;\n    }\n    event.preventDefault();\n    if (!this.parent?.isMultipleSelection) {\n      this.commitOrRemove();\n    }\n  }\n  commitOrRemove() {\n    if (this.isEmpty()) {\n      this.remove();\n    } else {\n      this.commit();\n    }\n  }\n  commit() {\n    this.addToAnnotationStorage();\n  }\n  addToAnnotationStorage() {\n    this._uiManager.addToAnnotationStorage(this);\n  }\n  setAt(x, y, tx, ty) {\n    const [width, height] = this.parentDimensions;\n    [tx, ty] = this.screenToPageTranslation(tx, ty);\n    this.x = (x + tx) / width;\n    this.y = (y + ty) / height;\n    this.fixAndSetPosition();\n  }\n  #translate([width, height], x, y) {\n    [x, y] = this.screenToPageTranslation(x, y);\n    this.x += x / width;\n    this.y += y / height;\n    this.fixAndSetPosition();\n  }\n  translate(x, y) {\n    this.#translate(this.parentDimensions, x, y);\n  }\n  translateInPage(x, y) {\n    this.#translate(this.pageDimensions, x, y);\n    this.div.scrollIntoView({\n      block: \"nearest\"\n    });\n  }\n  drag(tx, ty) {\n    const [parentWidth, parentHeight] = this.parentDimensions;\n    this.x += tx / parentWidth;\n    this.y += ty / parentHeight;\n    if (this.parent && (this.x < 0 || this.x > 1 || this.y < 0 || this.y > 1)) {\n      const {\n        x,\n        y\n      } = this.div.getBoundingClientRect();\n      if (this.parent.findNewParent(this, x, y)) {\n        this.x -= Math.floor(this.x);\n        this.y -= Math.floor(this.y);\n      }\n    }\n    let {\n      x,\n      y\n    } = this;\n    const [bx, by] = this.getBaseTranslation();\n    x += bx;\n    y += by;\n    this.div.style.left = `${(100 * x).toFixed(2)}%`;\n    this.div.style.top = `${(100 * y).toFixed(2)}%`;\n    this.div.scrollIntoView({\n      block: \"nearest\"\n    });\n  }\n  getBaseTranslation() {\n    const [parentWidth, parentHeight] = this.parentDimensions;\n    const {\n      _borderLineWidth\n    } = AnnotationEditor;\n    const x = _borderLineWidth / parentWidth;\n    const y = _borderLineWidth / parentHeight;\n    switch (this.rotation) {\n      case 90:\n        return [-x, y];\n      case 180:\n        return [x, y];\n      case 270:\n        return [x, -y];\n      default:\n        return [-x, -y];\n    }\n  }\n  get _mustFixPosition() {\n    return true;\n  }\n  fixAndSetPosition(rotation = this.rotation) {\n    const [pageWidth, pageHeight] = this.pageDimensions;\n    let {\n      x,\n      y,\n      width,\n      height\n    } = this;\n    width *= pageWidth;\n    height *= pageHeight;\n    x *= pageWidth;\n    y *= pageHeight;\n    if (this._mustFixPosition) {\n      switch (rotation) {\n        case 0:\n          x = Math.max(0, Math.min(pageWidth - width, x));\n          y = Math.max(0, Math.min(pageHeight - height, y));\n          break;\n        case 90:\n          x = Math.max(0, Math.min(pageWidth - height, x));\n          y = Math.min(pageHeight, Math.max(width, y));\n          break;\n        case 180:\n          x = Math.min(pageWidth, Math.max(width, x));\n          y = Math.min(pageHeight, Math.max(height, y));\n          break;\n        case 270:\n          x = Math.min(pageWidth, Math.max(height, x));\n          y = Math.max(0, Math.min(pageHeight - width, y));\n          break;\n      }\n    }\n    this.x = x /= pageWidth;\n    this.y = y /= pageHeight;\n    const [bx, by] = this.getBaseTranslation();\n    x += bx;\n    y += by;\n    const {\n      style\n    } = this.div;\n    style.left = `${(100 * x).toFixed(2)}%`;\n    style.top = `${(100 * y).toFixed(2)}%`;\n    this.moveInDOM();\n  }\n  static #rotatePoint(x, y, angle) {\n    switch (angle) {\n      case 90:\n        return [y, -x];\n      case 180:\n        return [-x, -y];\n      case 270:\n        return [-y, x];\n      default:\n        return [x, y];\n    }\n  }\n  screenToPageTranslation(x, y) {\n    return AnnotationEditor.#rotatePoint(x, y, this.parentRotation);\n  }\n  pageTranslationToScreen(x, y) {\n    return AnnotationEditor.#rotatePoint(x, y, 360 - this.parentRotation);\n  }\n  #getRotationMatrix(rotation) {\n    switch (rotation) {\n      case 90:\n        {\n          const [pageWidth, pageHeight] = this.pageDimensions;\n          return [0, -pageWidth / pageHeight, pageHeight / pageWidth, 0];\n        }\n      case 180:\n        return [-1, 0, 0, -1];\n      case 270:\n        {\n          const [pageWidth, pageHeight] = this.pageDimensions;\n          return [0, pageWidth / pageHeight, -pageHeight / pageWidth, 0];\n        }\n      default:\n        return [1, 0, 0, 1];\n    }\n  }\n  get parentScale() {\n    return this._uiManager.viewParameters.realScale;\n  }\n  get parentRotation() {\n    return (this._uiManager.viewParameters.rotation + this.pageRotation) % 360;\n  }\n  get parentDimensions() {\n    const {\n      parentScale,\n      pageDimensions: [pageWidth, pageHeight]\n    } = this;\n    const scaledWidth = pageWidth * parentScale;\n    const scaledHeight = pageHeight * parentScale;\n    return util.FeatureTest.isCSSRoundSupported ? [Math.round(scaledWidth), Math.round(scaledHeight)] : [scaledWidth, scaledHeight];\n  }\n  setDims(width, height) {\n    const [parentWidth, parentHeight] = this.parentDimensions;\n    this.div.style.width = `${(100 * width / parentWidth).toFixed(2)}%`;\n    if (!this.#keepAspectRatio) {\n      this.div.style.height = `${(100 * height / parentHeight).toFixed(2)}%`;\n    }\n  }\n  fixDims() {\n    const {\n      style\n    } = this.div;\n    const {\n      height,\n      width\n    } = style;\n    const widthPercent = width.endsWith(\"%\");\n    const heightPercent = !this.#keepAspectRatio && height.endsWith(\"%\");\n    if (widthPercent && heightPercent) {\n      return;\n    }\n    const [parentWidth, parentHeight] = this.parentDimensions;\n    if (!widthPercent) {\n      style.width = `${(100 * parseFloat(width) / parentWidth).toFixed(2)}%`;\n    }\n    if (!this.#keepAspectRatio && !heightPercent) {\n      style.height = `${(100 * parseFloat(height) / parentHeight).toFixed(2)}%`;\n    }\n  }\n  getInitialTranslation() {\n    return [0, 0];\n  }\n  #createResizers() {\n    if (this.#resizersDiv) {\n      return;\n    }\n    this.#resizersDiv = document.createElement(\"div\");\n    this.#resizersDiv.classList.add(\"resizers\");\n    const classes = this._willKeepAspectRatio ? [\"topLeft\", \"topRight\", \"bottomRight\", \"bottomLeft\"] : [\"topLeft\", \"topMiddle\", \"topRight\", \"middleRight\", \"bottomRight\", \"bottomMiddle\", \"bottomLeft\", \"middleLeft\"];\n    for (const name of classes) {\n      const div = document.createElement(\"div\");\n      this.#resizersDiv.append(div);\n      div.classList.add(\"resizer\", name);\n      div.setAttribute(\"data-resizer-name\", name);\n      div.addEventListener(\"pointerdown\", this.#resizerPointerdown.bind(this, name));\n      div.addEventListener(\"contextmenu\", display_utils.noContextMenu);\n      div.tabIndex = -1;\n    }\n    this.div.prepend(this.#resizersDiv);\n  }\n  #resizerPointerdown(name, event) {\n    event.preventDefault();\n    const {\n      isMac\n    } = util.FeatureTest.platform;\n    if (event.button !== 0 || event.ctrlKey && isMac) {\n      return;\n    }\n    this.#altText?.toggle(false);\n    const boundResizerPointermove = this.#resizerPointermove.bind(this, name);\n    const savedDraggable = this._isDraggable;\n    this._isDraggable = false;\n    const pointerMoveOptions = {\n      passive: true,\n      capture: true\n    };\n    this.parent.togglePointerEvents(false);\n    window.addEventListener(\"pointermove\", boundResizerPointermove, pointerMoveOptions);\n    const savedX = this.x;\n    const savedY = this.y;\n    const savedWidth = this.width;\n    const savedHeight = this.height;\n    const savedParentCursor = this.parent.div.style.cursor;\n    const savedCursor = this.div.style.cursor;\n    this.div.style.cursor = this.parent.div.style.cursor = window.getComputedStyle(event.target).cursor;\n    const pointerUpCallback = () => {\n      this.parent.togglePointerEvents(true);\n      this.#altText?.toggle(true);\n      this._isDraggable = savedDraggable;\n      window.removeEventListener(\"pointerup\", pointerUpCallback);\n      window.removeEventListener(\"blur\", pointerUpCallback);\n      window.removeEventListener(\"pointermove\", boundResizerPointermove, pointerMoveOptions);\n      this.parent.div.style.cursor = savedParentCursor;\n      this.div.style.cursor = savedCursor;\n      this.#addResizeToUndoStack(savedX, savedY, savedWidth, savedHeight);\n    };\n    window.addEventListener(\"pointerup\", pointerUpCallback);\n    window.addEventListener(\"blur\", pointerUpCallback);\n  }\n  #addResizeToUndoStack(savedX, savedY, savedWidth, savedHeight) {\n    const newX = this.x;\n    const newY = this.y;\n    const newWidth = this.width;\n    const newHeight = this.height;\n    if (newX === savedX && newY === savedY && newWidth === savedWidth && newHeight === savedHeight) {\n      return;\n    }\n    this.addCommands({\n      cmd: () => {\n        this.width = newWidth;\n        this.height = newHeight;\n        this.x = newX;\n        this.y = newY;\n        const [parentWidth, parentHeight] = this.parentDimensions;\n        this.setDims(parentWidth * newWidth, parentHeight * newHeight);\n        this.fixAndSetPosition();\n      },\n      undo: () => {\n        this.width = savedWidth;\n        this.height = savedHeight;\n        this.x = savedX;\n        this.y = savedY;\n        const [parentWidth, parentHeight] = this.parentDimensions;\n        this.setDims(parentWidth * savedWidth, parentHeight * savedHeight);\n        this.fixAndSetPosition();\n      },\n      mustExec: true\n    });\n  }\n  #resizerPointermove(name, event) {\n    const [parentWidth, parentHeight] = this.parentDimensions;\n    const savedX = this.x;\n    const savedY = this.y;\n    const savedWidth = this.width;\n    const savedHeight = this.height;\n    const minWidth = AnnotationEditor.MIN_SIZE / parentWidth;\n    const minHeight = AnnotationEditor.MIN_SIZE / parentHeight;\n    const round = x => Math.round(x * 10000) / 10000;\n    const rotationMatrix = this.#getRotationMatrix(this.rotation);\n    const transf = (x, y) => [rotationMatrix[0] * x + rotationMatrix[2] * y, rotationMatrix[1] * x + rotationMatrix[3] * y];\n    const invRotationMatrix = this.#getRotationMatrix(360 - this.rotation);\n    const invTransf = (x, y) => [invRotationMatrix[0] * x + invRotationMatrix[2] * y, invRotationMatrix[1] * x + invRotationMatrix[3] * y];\n    let getPoint;\n    let getOpposite;\n    let isDiagonal = false;\n    let isHorizontal = false;\n    switch (name) {\n      case \"topLeft\":\n        isDiagonal = true;\n        getPoint = (w, h) => [0, 0];\n        getOpposite = (w, h) => [w, h];\n        break;\n      case \"topMiddle\":\n        getPoint = (w, h) => [w / 2, 0];\n        getOpposite = (w, h) => [w / 2, h];\n        break;\n      case \"topRight\":\n        isDiagonal = true;\n        getPoint = (w, h) => [w, 0];\n        getOpposite = (w, h) => [0, h];\n        break;\n      case \"middleRight\":\n        isHorizontal = true;\n        getPoint = (w, h) => [w, h / 2];\n        getOpposite = (w, h) => [0, h / 2];\n        break;\n      case \"bottomRight\":\n        isDiagonal = true;\n        getPoint = (w, h) => [w, h];\n        getOpposite = (w, h) => [0, 0];\n        break;\n      case \"bottomMiddle\":\n        getPoint = (w, h) => [w / 2, h];\n        getOpposite = (w, h) => [w / 2, 0];\n        break;\n      case \"bottomLeft\":\n        isDiagonal = true;\n        getPoint = (w, h) => [0, h];\n        getOpposite = (w, h) => [w, 0];\n        break;\n      case \"middleLeft\":\n        isHorizontal = true;\n        getPoint = (w, h) => [0, h / 2];\n        getOpposite = (w, h) => [w, h / 2];\n        break;\n    }\n    const point = getPoint(savedWidth, savedHeight);\n    const oppositePoint = getOpposite(savedWidth, savedHeight);\n    let transfOppositePoint = transf(...oppositePoint);\n    const oppositeX = round(savedX + transfOppositePoint[0]);\n    const oppositeY = round(savedY + transfOppositePoint[1]);\n    let ratioX = 1;\n    let ratioY = 1;\n    let [deltaX, deltaY] = this.screenToPageTranslation(event.movementX, event.movementY);\n    [deltaX, deltaY] = invTransf(deltaX / parentWidth, deltaY / parentHeight);\n    if (isDiagonal) {\n      const oldDiag = Math.hypot(savedWidth, savedHeight);\n      ratioX = ratioY = Math.max(Math.min(Math.hypot(oppositePoint[0] - point[0] - deltaX, oppositePoint[1] - point[1] - deltaY) / oldDiag, 1 / savedWidth, 1 / savedHeight), minWidth / savedWidth, minHeight / savedHeight);\n    } else if (isHorizontal) {\n      ratioX = Math.max(minWidth, Math.min(1, Math.abs(oppositePoint[0] - point[0] - deltaX))) / savedWidth;\n    } else {\n      ratioY = Math.max(minHeight, Math.min(1, Math.abs(oppositePoint[1] - point[1] - deltaY))) / savedHeight;\n    }\n    const newWidth = round(savedWidth * ratioX);\n    const newHeight = round(savedHeight * ratioY);\n    transfOppositePoint = transf(...getOpposite(newWidth, newHeight));\n    const newX = oppositeX - transfOppositePoint[0];\n    const newY = oppositeY - transfOppositePoint[1];\n    this.width = newWidth;\n    this.height = newHeight;\n    this.x = newX;\n    this.y = newY;\n    this.setDims(parentWidth * newWidth, parentHeight * newHeight);\n    this.fixAndSetPosition();\n  }\n  altTextFinish() {\n    this.#altText?.finish();\n  }\n  async addEditToolbar() {\n    if (this.#editToolbar || this.#isInEditMode) {\n      return this.#editToolbar;\n    }\n    this.#editToolbar = new toolbar.EditorToolbar(this);\n    this.div.append(this.#editToolbar.render());\n    if (this.#altText) {\n      this.#editToolbar.addAltTextButton(await this.#altText.render());\n    }\n    return this.#editToolbar;\n  }\n  removeEditToolbar() {\n    if (!this.#editToolbar) {\n      return;\n    }\n    this.#editToolbar.remove();\n    this.#editToolbar = null;\n    this.#altText?.destroy();\n  }\n  getClientDimensions() {\n    return this.div.getBoundingClientRect();\n  }\n  async addAltTextButton() {\n    if (this.#altText) {\n      return;\n    }\n    AltText.initialize(AnnotationEditor._l10nPromise);\n    this.#altText = new AltText(this);\n    await this.addEditToolbar();\n  }\n  get altTextData() {\n    return this.#altText?.data;\n  }\n  set altTextData(data) {\n    if (!this.#altText) {\n      return;\n    }\n    this.#altText.data = data;\n  }\n  hasAltText() {\n    return !this.#altText?.isEmpty();\n  }\n  render() {\n    this.div = document.createElement(\"div\");\n    this.div.setAttribute(\"data-editor-rotation\", (360 - this.rotation) % 360);\n    this.div.className = this.name;\n    this.div.setAttribute(\"id\", this.id);\n    this.div.setAttribute(\"tabIndex\", 0);\n    if (!this._isVisible) {\n      this.div.classList.add(\"hidden\");\n    }\n    this.setInForeground();\n    this.div.addEventListener(\"focusin\", this.#boundFocusin);\n    this.div.addEventListener(\"focusout\", this.#boundFocusout);\n    const [parentWidth, parentHeight] = this.parentDimensions;\n    if (this.parentRotation % 180 !== 0) {\n      this.div.style.maxWidth = `${(100 * parentHeight / parentWidth).toFixed(2)}%`;\n      this.div.style.maxHeight = `${(100 * parentWidth / parentHeight).toFixed(2)}%`;\n    }\n    const [tx, ty] = this.getInitialTranslation();\n    this.translate(tx, ty);\n    (0,tools.bindEvents)(this, this.div, [\"pointerdown\"]);\n    return this.div;\n  }\n  pointerdown(event) {\n    const {\n      isMac\n    } = util.FeatureTest.platform;\n    if (event.button !== 0 || event.ctrlKey && isMac) {\n      event.preventDefault();\n      return;\n    }\n    this.#hasBeenClicked = true;\n    if (this._isDraggable) {\n      this.#setUpDragSession(event);\n      return;\n    }\n    this.#selectOnPointerEvent(event);\n  }\n  #selectOnPointerEvent(event) {\n    const {\n      isMac\n    } = util.FeatureTest.platform;\n    if (event.ctrlKey && !isMac || event.shiftKey || event.metaKey && isMac) {\n      this.parent.toggleSelected(this);\n    } else {\n      this.parent.setSelected(this);\n    }\n  }\n  #setUpDragSession(event) {\n    const isSelected = this._uiManager.isSelected(this);\n    this._uiManager.setUpDragSession();\n    let pointerMoveOptions, pointerMoveCallback;\n    if (isSelected) {\n      this.div.classList.add(\"moving\");\n      pointerMoveOptions = {\n        passive: true,\n        capture: true\n      };\n      this.#prevDragX = event.clientX;\n      this.#prevDragY = event.clientY;\n      pointerMoveCallback = e => {\n        const {\n          clientX: x,\n          clientY: y\n        } = e;\n        const [tx, ty] = this.screenToPageTranslation(x - this.#prevDragX, y - this.#prevDragY);\n        this.#prevDragX = x;\n        this.#prevDragY = y;\n        this._uiManager.dragSelectedEditors(tx, ty);\n      };\n      window.addEventListener(\"pointermove\", pointerMoveCallback, pointerMoveOptions);\n    }\n    const pointerUpCallback = () => {\n      window.removeEventListener(\"pointerup\", pointerUpCallback);\n      window.removeEventListener(\"blur\", pointerUpCallback);\n      if (isSelected) {\n        this.div.classList.remove(\"moving\");\n        window.removeEventListener(\"pointermove\", pointerMoveCallback, pointerMoveOptions);\n      }\n      this.#hasBeenClicked = false;\n      if (!this._uiManager.endDragSession()) {\n        this.#selectOnPointerEvent(event);\n      }\n    };\n    window.addEventListener(\"pointerup\", pointerUpCallback);\n    window.addEventListener(\"blur\", pointerUpCallback);\n  }\n  moveInDOM() {\n    if (this.#moveInDOMTimeout) {\n      clearTimeout(this.#moveInDOMTimeout);\n    }\n    this.#moveInDOMTimeout = setTimeout(() => {\n      this.#moveInDOMTimeout = null;\n      this.parent?.moveEditorInDOM(this);\n    }, 0);\n  }\n  _setParentAndPosition(parent, x, y) {\n    parent.changeParent(this);\n    this.x = x;\n    this.y = y;\n    this.fixAndSetPosition();\n  }\n  getRect(tx, ty, rotation = this.rotation) {\n    const scale = this.parentScale;\n    const [pageWidth, pageHeight] = this.pageDimensions;\n    const [pageX, pageY] = this.pageTranslation;\n    const shiftX = tx / scale;\n    const shiftY = ty / scale;\n    const x = this.x * pageWidth;\n    const y = this.y * pageHeight;\n    const width = this.width * pageWidth;\n    const height = this.height * pageHeight;\n    switch (rotation) {\n      case 0:\n        return [x + shiftX + pageX, pageHeight - y - shiftY - height + pageY, x + shiftX + width + pageX, pageHeight - y - shiftY + pageY];\n      case 90:\n        return [x + shiftY + pageX, pageHeight - y + shiftX + pageY, x + shiftY + height + pageX, pageHeight - y + shiftX + width + pageY];\n      case 180:\n        return [x - shiftX - width + pageX, pageHeight - y + shiftY + pageY, x - shiftX + pageX, pageHeight - y + shiftY + height + pageY];\n      case 270:\n        return [x - shiftY - height + pageX, pageHeight - y - shiftX - width + pageY, x - shiftY + pageX, pageHeight - y - shiftX + pageY];\n      default:\n        throw new Error(\"Invalid rotation\");\n    }\n  }\n  getRectInCurrentCoords(rect, pageHeight) {\n    const [x1, y1, x2, y2] = rect;\n    const width = x2 - x1;\n    const height = y2 - y1;\n    switch (this.rotation) {\n      case 0:\n        return [x1, pageHeight - y2, width, height];\n      case 90:\n        return [x1, pageHeight - y1, height, width];\n      case 180:\n        return [x2, pageHeight - y1, width, height];\n      case 270:\n        return [x2, pageHeight - y2, height, width];\n      default:\n        throw new Error(\"Invalid rotation\");\n    }\n  }\n  onceAdded() {}\n  isEmpty() {\n    return false;\n  }\n  enableEditMode() {\n    this.#isInEditMode = true;\n  }\n  disableEditMode() {\n    this.#isInEditMode = false;\n  }\n  isInEditMode() {\n    return this.#isInEditMode;\n  }\n  shouldGetKeyboardEvents() {\n    return this.#isResizerEnabledForKeyboard;\n  }\n  needsToBeRebuilt() {\n    return this.div && !this.isAttachedToDOM;\n  }\n  rebuild() {\n    this.div?.addEventListener(\"focusin\", this.#boundFocusin);\n    this.div?.addEventListener(\"focusout\", this.#boundFocusout);\n    this.show(this._isVisible);\n  }\n  rotate(_angle) {}\n  serialize(isForCopying = false, context = null) {\n    (0,util.unreachable)(\"An editor must be serializable\");\n  }\n  static deserialize(data, parent, uiManager) {\n    const editor = new this.prototype.constructor({\n      parent,\n      id: parent.getNextId(),\n      uiManager\n    });\n    editor.rotation = data.rotation;\n    const [pageWidth, pageHeight] = editor.pageDimensions;\n    const [x, y, width, height] = editor.getRectInCurrentCoords(data.rect, pageHeight);\n    editor.x = x / pageWidth;\n    editor.y = y / pageHeight;\n    editor.width = width / pageWidth;\n    editor.height = height / pageHeight;\n    return editor;\n  }\n  remove() {\n    this.div.removeEventListener(\"focusin\", this.#boundFocusin);\n    this.div.removeEventListener(\"focusout\", this.#boundFocusout);\n    if (!this.isEmpty()) {\n      this.commit();\n    }\n    if (this.parent) {\n      this.parent.remove(this);\n    } else {\n      this._uiManager.removeEditor(this);\n    }\n    if (this.#moveInDOMTimeout) {\n      clearTimeout(this.#moveInDOMTimeout);\n      this.#moveInDOMTimeout = null;\n    }\n    this.#stopResizing();\n    this.removeEditToolbar();\n    if (this.#telemetryTimeouts) {\n      for (const timeout of this.#telemetryTimeouts.values()) {\n        clearTimeout(timeout);\n      }\n      this.#telemetryTimeouts = null;\n    }\n  }\n  get isResizable() {\n    return false;\n  }\n  makeResizable() {\n    if (this.isResizable) {\n      this.#createResizers();\n      this.#resizersDiv.classList.remove(\"hidden\");\n      (0,tools.bindEvents)(this, this.div, [\"keydown\"]);\n    }\n  }\n  get toolbarPosition() {\n    return null;\n  }\n  keydown(event) {\n    if (!this.isResizable || event.target !== this.div || event.key !== \"Enter\") {\n      return;\n    }\n    this._uiManager.setSelected(this);\n    this.#savedDimensions = {\n      savedX: this.x,\n      savedY: this.y,\n      savedWidth: this.width,\n      savedHeight: this.height\n    };\n    const children = this.#resizersDiv.children;\n    if (!this.#allResizerDivs) {\n      this.#allResizerDivs = Array.from(children);\n      const boundResizerKeydown = this.#resizerKeydown.bind(this);\n      const boundResizerBlur = this.#resizerBlur.bind(this);\n      for (const div of this.#allResizerDivs) {\n        const name = div.getAttribute(\"data-resizer-name\");\n        div.setAttribute(\"role\", \"spinbutton\");\n        div.addEventListener(\"keydown\", boundResizerKeydown);\n        div.addEventListener(\"blur\", boundResizerBlur);\n        div.addEventListener(\"focus\", this.#resizerFocus.bind(this, name));\n        AnnotationEditor._l10nPromise.get(`pdfjs-editor-resizer-label-${name}`).then(msg => div.setAttribute(\"aria-label\", msg));\n      }\n    }\n    const first = this.#allResizerDivs[0];\n    let firstPosition = 0;\n    for (const div of children) {\n      if (div === first) {\n        break;\n      }\n      firstPosition++;\n    }\n    const nextFirstPosition = (360 - this.rotation + this.parentRotation) % 360 / 90 * (this.#allResizerDivs.length / 4);\n    if (nextFirstPosition !== firstPosition) {\n      if (nextFirstPosition < firstPosition) {\n        for (let i = 0; i < firstPosition - nextFirstPosition; i++) {\n          this.#resizersDiv.append(this.#resizersDiv.firstChild);\n        }\n      } else if (nextFirstPosition > firstPosition) {\n        for (let i = 0; i < nextFirstPosition - firstPosition; i++) {\n          this.#resizersDiv.firstChild.before(this.#resizersDiv.lastChild);\n        }\n      }\n      let i = 0;\n      for (const child of children) {\n        const div = this.#allResizerDivs[i++];\n        const name = div.getAttribute(\"data-resizer-name\");\n        AnnotationEditor._l10nPromise.get(`pdfjs-editor-resizer-label-${name}`).then(msg => child.setAttribute(\"aria-label\", msg));\n      }\n    }\n    this.#setResizerTabIndex(0);\n    this.#isResizerEnabledForKeyboard = true;\n    this.#resizersDiv.firstChild.focus({\n      focusVisible: true\n    });\n    event.preventDefault();\n    event.stopImmediatePropagation();\n  }\n  #resizerKeydown(event) {\n    AnnotationEditor._resizerKeyboardManager.exec(this, event);\n  }\n  #resizerBlur(event) {\n    if (this.#isResizerEnabledForKeyboard && event.relatedTarget?.parentNode !== this.#resizersDiv) {\n      this.#stopResizing();\n    }\n  }\n  #resizerFocus(name) {\n    this.#focusedResizerName = this.#isResizerEnabledForKeyboard ? name : \"\";\n  }\n  #setResizerTabIndex(value) {\n    if (!this.#allResizerDivs) {\n      return;\n    }\n    for (const div of this.#allResizerDivs) {\n      div.tabIndex = value;\n    }\n  }\n  _resizeWithKeyboard(x, y) {\n    if (!this.#isResizerEnabledForKeyboard) {\n      return;\n    }\n    this.#resizerPointermove(this.#focusedResizerName, {\n      movementX: x,\n      movementY: y\n    });\n  }\n  #stopResizing() {\n    this.#isResizerEnabledForKeyboard = false;\n    this.#setResizerTabIndex(-1);\n    if (this.#savedDimensions) {\n      const {\n        savedX,\n        savedY,\n        savedWidth,\n        savedHeight\n      } = this.#savedDimensions;\n      this.#addResizeToUndoStack(savedX, savedY, savedWidth, savedHeight);\n      this.#savedDimensions = null;\n    }\n  }\n  _stopResizingWithKeyboard() {\n    this.#stopResizing();\n    this.div.focus();\n  }\n  select() {\n    this.makeResizable();\n    this.div?.classList.add(\"selectedEditor\");\n    if (!this.#editToolbar) {\n      this.addEditToolbar().then(() => {\n        if (this.div?.classList.contains(\"selectedEditor\")) {\n          this.#editToolbar?.show();\n        }\n      });\n      return;\n    }\n    this.#editToolbar?.show();\n  }\n  unselect() {\n    this.#resizersDiv?.classList.add(\"hidden\");\n    this.div?.classList.remove(\"selectedEditor\");\n    if (this.div?.contains(document.activeElement)) {\n      this._uiManager.currentLayer.div.focus({\n        preventScroll: true\n      });\n    }\n    this.#editToolbar?.hide();\n  }\n  updateParams(type, value) {}\n  disableEditing() {}\n  enableEditing() {}\n  enterInEditMode() {}\n  getImageForAltText() {\n    return null;\n  }\n  get contentDiv() {\n    return this.div;\n  }\n  get isEditing() {\n    return this.#isEditing;\n  }\n  set isEditing(value) {\n    this.#isEditing = value;\n    if (!this.parent) {\n      return;\n    }\n    if (value) {\n      this.parent.setSelected(this);\n      this.parent.setActiveEditor(this);\n    } else {\n      this.parent.setActiveEditor(null);\n    }\n  }\n  setAspectRatio(width, height) {\n    this.#keepAspectRatio = true;\n    const aspectRatio = width / height;\n    const {\n      style\n    } = this.div;\n    style.aspectRatio = aspectRatio;\n    style.height = \"auto\";\n  }\n  static get MIN_SIZE() {\n    return 16;\n  }\n  static canCreateNewEmptyEditor() {\n    return true;\n  }\n  get telemetryInitialData() {\n    return {\n      action: \"added\"\n    };\n  }\n  get telemetryFinalData() {\n    return null;\n  }\n  _reportTelemetry(data, mustWait = false) {\n    if (mustWait) {\n      this.#telemetryTimeouts ||= new Map();\n      const {\n        action\n      } = data;\n      let timeout = this.#telemetryTimeouts.get(action);\n      if (timeout) {\n        clearTimeout(timeout);\n      }\n      timeout = setTimeout(() => {\n        this._reportTelemetry(data);\n        this.#telemetryTimeouts.delete(action);\n        if (this.#telemetryTimeouts.size === 0) {\n          this.#telemetryTimeouts = null;\n        }\n      }, AnnotationEditor._telemetryTimeout);\n      this.#telemetryTimeouts.set(action, timeout);\n      return;\n    }\n    data.type ||= this.editorType;\n    this._uiManager._eventBus.dispatch(\"reporttelemetry\", {\n      source: this,\n      details: {\n        type: \"editing\",\n        data\n      }\n    });\n  }\n  show(visible) {\n    this.div.classList.toggle(\"hidden\", !visible);\n    this._isVisible = visible;\n  }\n}\nclass FakeEditor extends AnnotationEditor {\n  constructor(params) {\n    super(params);\n    this.annotationElementId = params.annotationElementId;\n    this.deleted = true;\n  }\n  serialize() {\n    return {\n      id: this.annotationElementId,\n      deleted: true,\n      pageIndex: this.pageIndex\n    };\n  }\n}\n\n\n/***/ }),\n\n/***/ 362:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   EditorToolbar: () => (/* binding */ EditorToolbar),\n/* harmony export */   HighlightToolbar: () => (/* binding */ HighlightToolbar)\n/* harmony export */ });\n/* harmony import */ var _display_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(419);\n\nclass EditorToolbar {\n  #toolbar = null;\n  #colorPicker = null;\n  #editor;\n  #buttons = null;\n  constructor(editor) {\n    this.#editor = editor;\n  }\n  render() {\n    const editToolbar = this.#toolbar = document.createElement(\"div\");\n    editToolbar.className = \"editToolbar\";\n    editToolbar.setAttribute(\"role\", \"toolbar\");\n    editToolbar.addEventListener(\"contextmenu\", _display_utils_js__WEBPACK_IMPORTED_MODULE_0__.noContextMenu);\n    editToolbar.addEventListener(\"pointerdown\", EditorToolbar.#pointerDown);\n    const buttons = this.#buttons = document.createElement(\"div\");\n    buttons.className = \"buttons\";\n    editToolbar.append(buttons);\n    const position = this.#editor.toolbarPosition;\n    if (position) {\n      const {\n        style\n      } = editToolbar;\n      const x = this.#editor._uiManager.direction === \"ltr\" ? 1 - position[0] : position[0];\n      style.insetInlineEnd = `${100 * x}%`;\n      style.top = `calc(${100 * position[1]}% + var(--editor-toolbar-vert-offset))`;\n    }\n    this.#addDeleteButton();\n    return editToolbar;\n  }\n  static #pointerDown(e) {\n    e.stopPropagation();\n  }\n  #focusIn(e) {\n    this.#editor._focusEventsAllowed = false;\n    e.preventDefault();\n    e.stopPropagation();\n  }\n  #focusOut(e) {\n    this.#editor._focusEventsAllowed = true;\n    e.preventDefault();\n    e.stopPropagation();\n  }\n  #addListenersToElement(element) {\n    element.addEventListener(\"focusin\", this.#focusIn.bind(this), {\n      capture: true\n    });\n    element.addEventListener(\"focusout\", this.#focusOut.bind(this), {\n      capture: true\n    });\n    element.addEventListener(\"contextmenu\", _display_utils_js__WEBPACK_IMPORTED_MODULE_0__.noContextMenu);\n  }\n  hide() {\n    this.#toolbar.classList.add(\"hidden\");\n    this.#colorPicker?.hideDropdown();\n  }\n  show() {\n    this.#toolbar.classList.remove(\"hidden\");\n  }\n  #addDeleteButton() {\n    const button = document.createElement(\"button\");\n    button.className = \"delete\";\n    button.tabIndex = 0;\n    button.setAttribute(\"data-l10n-id\", `pdfjs-editor-remove-${this.#editor.editorType}-button`);\n    this.#addListenersToElement(button);\n    button.addEventListener(\"click\", e => {\n      this.#editor._uiManager.delete();\n    });\n    this.#buttons.append(button);\n  }\n  get #divider() {\n    const divider = document.createElement(\"div\");\n    divider.className = \"divider\";\n    return divider;\n  }\n  addAltTextButton(button) {\n    this.#addListenersToElement(button);\n    this.#buttons.prepend(button, this.#divider);\n  }\n  addColorPicker(colorPicker) {\n    this.#colorPicker = colorPicker;\n    const button = colorPicker.renderButton();\n    this.#addListenersToElement(button);\n    this.#buttons.prepend(button, this.#divider);\n  }\n  remove() {\n    this.#toolbar.remove();\n    this.#colorPicker?.destroy();\n    this.#colorPicker = null;\n  }\n}\nclass HighlightToolbar {\n  #buttons = null;\n  #toolbar = null;\n  #uiManager;\n  constructor(uiManager) {\n    this.#uiManager = uiManager;\n  }\n  #render() {\n    const editToolbar = this.#toolbar = document.createElement(\"div\");\n    editToolbar.className = \"editToolbar\";\n    editToolbar.setAttribute(\"role\", \"toolbar\");\n    editToolbar.addEventListener(\"contextmenu\", _display_utils_js__WEBPACK_IMPORTED_MODULE_0__.noContextMenu);\n    const buttons = this.#buttons = document.createElement(\"div\");\n    buttons.className = \"buttons\";\n    editToolbar.append(buttons);\n    this.#addHighlightButton();\n    return editToolbar;\n  }\n  #getLastPoint(boxes, isLTR) {\n    let lastY = 0;\n    let lastX = 0;\n    for (const box of boxes) {\n      const y = box.y + box.height;\n      if (y < lastY) {\n        continue;\n      }\n      const x = box.x + (isLTR ? box.width : 0);\n      if (y > lastY) {\n        lastX = x;\n        lastY = y;\n        continue;\n      }\n      if (isLTR) {\n        if (x > lastX) {\n          lastX = x;\n        }\n      } else if (x < lastX) {\n        lastX = x;\n      }\n    }\n    return [isLTR ? 1 - lastX : lastX, lastY];\n  }\n  show(parent, boxes, isLTR) {\n    const [x, y] = this.#getLastPoint(boxes, isLTR);\n    const {\n      style\n    } = this.#toolbar ||= this.#render();\n    parent.append(this.#toolbar);\n    style.insetInlineEnd = `${100 * x}%`;\n    style.top = `calc(${100 * y}% + var(--editor-toolbar-vert-offset))`;\n  }\n  hide() {\n    this.#toolbar.remove();\n  }\n  #addHighlightButton() {\n    const button = document.createElement(\"button\");\n    button.className = \"highlightButton\";\n    button.tabIndex = 0;\n    button.setAttribute(\"data-l10n-id\", `pdfjs-highlight-floating-button`);\n    button.addEventListener(\"contextmenu\", _display_utils_js__WEBPACK_IMPORTED_MODULE_0__.noContextMenu);\n    button.addEventListener(\"click\", () => {\n      this.#uiManager.highlightSelection(\"floating_button\");\n    });\n    this.#buttons.append(button);\n  }\n}\n\n\n/***/ }),\n\n/***/ 419:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   DOMCMapReaderFactory: () => (/* binding */ DOMCMapReaderFactory),\n/* harmony export */   DOMCanvasFactory: () => (/* binding */ DOMCanvasFactory),\n/* harmony export */   DOMFilterFactory: () => (/* binding */ DOMFilterFactory),\n/* harmony export */   DOMSVGFactory: () => (/* binding */ DOMSVGFactory),\n/* harmony export */   DOMStandardFontDataFactory: () => (/* binding */ DOMStandardFontDataFactory),\n/* harmony export */   PDFDateString: () => (/* binding */ PDFDateString),\n/* harmony export */   PageViewport: () => (/* binding */ PageViewport),\n/* harmony export */   PixelsPerInch: () => (/* binding */ PixelsPerInch),\n/* harmony export */   RenderingCancelledException: () => (/* binding */ RenderingCancelledException),\n/* harmony export */   StatTimer: () => (/* binding */ StatTimer),\n/* harmony export */   fetchData: () => (/* binding */ fetchData),\n/* harmony export */   getColorValues: () => (/* binding */ getColorValues),\n/* harmony export */   getCurrentTransform: () => (/* binding */ getCurrentTransform),\n/* harmony export */   getCurrentTransformInverse: () => (/* binding */ getCurrentTransformInverse),\n/* harmony export */   getFilenameFromUrl: () => (/* binding */ getFilenameFromUrl),\n/* harmony export */   getPdfFilenameFromUrl: () => (/* binding */ getPdfFilenameFromUrl),\n/* harmony export */   getRGB: () => (/* binding */ getRGB),\n/* harmony export */   getXfaPageViewport: () => (/* binding */ getXfaPageViewport),\n/* harmony export */   isDataScheme: () => (/* binding */ isDataScheme),\n/* harmony export */   isPdfFile: () => (/* binding */ isPdfFile),\n/* harmony export */   isValidFetchUrl: () => (/* binding */ isValidFetchUrl),\n/* harmony export */   noContextMenu: () => (/* binding */ noContextMenu),\n/* harmony export */   setLayerDimensions: () => (/* binding */ setLayerDimensions)\n/* harmony export */ });\n/* unused harmony export deprecated */\n/* harmony import */ var _base_factory_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(583);\n/* harmony import */ var _shared_util_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(292);\n\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\nclass PixelsPerInch {\n  static CSS = 96.0;\n  static PDF = 72.0;\n  static PDF_TO_CSS_UNITS = this.CSS / this.PDF;\n}\nclass DOMFilterFactory extends _base_factory_js__WEBPACK_IMPORTED_MODULE_0__.BaseFilterFactory {\n  #_cache;\n  #_defs;\n  #docId;\n  #document;\n  #_hcmCache;\n  #id = 0;\n  constructor({\n    docId,\n    ownerDocument = globalThis.document\n  } = {}) {\n    super();\n    this.#docId = docId;\n    this.#document = ownerDocument;\n  }\n  get #cache() {\n    return this.#_cache ||= new Map();\n  }\n  get #hcmCache() {\n    return this.#_hcmCache ||= new Map();\n  }\n  get #defs() {\n    if (!this.#_defs) {\n      const div = this.#document.createElement(\"div\");\n      const {\n        style\n      } = div;\n      style.visibility = \"hidden\";\n      style.contain = \"strict\";\n      style.width = style.height = 0;\n      style.position = \"absolute\";\n      style.top = style.left = 0;\n      style.zIndex = -1;\n      const svg = this.#document.createElementNS(SVG_NS, \"svg\");\n      svg.setAttribute(\"width\", 0);\n      svg.setAttribute(\"height\", 0);\n      this.#_defs = this.#document.createElementNS(SVG_NS, \"defs\");\n      div.append(svg);\n      svg.append(this.#_defs);\n      this.#document.body.append(div);\n    }\n    return this.#_defs;\n  }\n  addFilter(maps) {\n    if (!maps) {\n      return \"none\";\n    }\n    let value = this.#cache.get(maps);\n    if (value) {\n      return value;\n    }\n    let tableR, tableG, tableB, key;\n    if (maps.length === 1) {\n      const mapR = maps[0];\n      const buffer = new Array(256);\n      for (let i = 0; i < 256; i++) {\n        buffer[i] = mapR[i] / 255;\n      }\n      key = tableR = tableG = tableB = buffer.join(\",\");\n    } else {\n      const [mapR, mapG, mapB] = maps;\n      const bufferR = new Array(256);\n      const bufferG = new Array(256);\n      const bufferB = new Array(256);\n      for (let i = 0; i < 256; i++) {\n        bufferR[i] = mapR[i] / 255;\n        bufferG[i] = mapG[i] / 255;\n        bufferB[i] = mapB[i] / 255;\n      }\n      tableR = bufferR.join(\",\");\n      tableG = bufferG.join(\",\");\n      tableB = bufferB.join(\",\");\n      key = `${tableR}${tableG}${tableB}`;\n    }\n    value = this.#cache.get(key);\n    if (value) {\n      this.#cache.set(maps, value);\n      return value;\n    }\n    const id = `g_${this.#docId}_transfer_map_${this.#id++}`;\n    const url = `url(#${id})`;\n    this.#cache.set(maps, url);\n    this.#cache.set(key, url);\n    const filter = this.#createFilter(id);\n    this.#addTransferMapConversion(tableR, tableG, tableB, filter);\n    return url;\n  }\n  addHCMFilter(fgColor, bgColor) {\n    const key = `${fgColor}-${bgColor}`;\n    const filterName = \"base\";\n    let info = this.#hcmCache.get(filterName);\n    if (info?.key === key) {\n      return info.url;\n    }\n    if (info) {\n      info.filter?.remove();\n      info.key = key;\n      info.url = \"none\";\n      info.filter = null;\n    } else {\n      info = {\n        key,\n        url: \"none\",\n        filter: null\n      };\n      this.#hcmCache.set(filterName, info);\n    }\n    if (!fgColor || !bgColor) {\n      return info.url;\n    }\n    const fgRGB = this.#getRGB(fgColor);\n    fgColor = _shared_util_js__WEBPACK_IMPORTED_MODULE_1__.Util.makeHexColor(...fgRGB);\n    const bgRGB = this.#getRGB(bgColor);\n    bgColor = _shared_util_js__WEBPACK_IMPORTED_MODULE_1__.Util.makeHexColor(...bgRGB);\n    this.#defs.style.color = \"\";\n    if (fgColor === \"#000000\" && bgColor === \"#ffffff\" || fgColor === bgColor) {\n      return info.url;\n    }\n    const map = new Array(256);\n    for (let i = 0; i <= 255; i++) {\n      const x = i / 255;\n      map[i] = x <= 0.03928 ? x / 12.92 : ((x + 0.055) / 1.055) ** 2.4;\n    }\n    const table = map.join(\",\");\n    const id = `g_${this.#docId}_hcm_filter`;\n    const filter = info.filter = this.#createFilter(id);\n    this.#addTransferMapConversion(table, table, table, filter);\n    this.#addGrayConversion(filter);\n    const getSteps = (c, n) => {\n      const start = fgRGB[c] / 255;\n      const end = bgRGB[c] / 255;\n      const arr = new Array(n + 1);\n      for (let i = 0; i <= n; i++) {\n        arr[i] = start + i / n * (end - start);\n      }\n      return arr.join(\",\");\n    };\n    this.#addTransferMapConversion(getSteps(0, 5), getSteps(1, 5), getSteps(2, 5), filter);\n    info.url = `url(#${id})`;\n    return info.url;\n  }\n  addHighlightHCMFilter(filterName, fgColor, bgColor, newFgColor, newBgColor) {\n    const key = `${fgColor}-${bgColor}-${newFgColor}-${newBgColor}`;\n    let info = this.#hcmCache.get(filterName);\n    if (info?.key === key) {\n      return info.url;\n    }\n    if (info) {\n      info.filter?.remove();\n      info.key = key;\n      info.url = \"none\";\n      info.filter = null;\n    } else {\n      info = {\n        key,\n        url: \"none\",\n        filter: null\n      };\n      this.#hcmCache.set(filterName, info);\n    }\n    if (!fgColor || !bgColor) {\n      return info.url;\n    }\n    const [fgRGB, bgRGB] = [fgColor, bgColor].map(this.#getRGB.bind(this));\n    let fgGray = Math.round(0.2126 * fgRGB[0] + 0.7152 * fgRGB[1] + 0.0722 * fgRGB[2]);\n    let bgGray = Math.round(0.2126 * bgRGB[0] + 0.7152 * bgRGB[1] + 0.0722 * bgRGB[2]);\n    let [newFgRGB, newBgRGB] = [newFgColor, newBgColor].map(this.#getRGB.bind(this));\n    if (bgGray < fgGray) {\n      [fgGray, bgGray, newFgRGB, newBgRGB] = [bgGray, fgGray, newBgRGB, newFgRGB];\n    }\n    this.#defs.style.color = \"\";\n    const getSteps = (fg, bg, n) => {\n      const arr = new Array(256);\n      const step = (bgGray - fgGray) / n;\n      const newStart = fg / 255;\n      const newStep = (bg - fg) / (255 * n);\n      let prev = 0;\n      for (let i = 0; i <= n; i++) {\n        const k = Math.round(fgGray + i * step);\n        const value = newStart + i * newStep;\n        for (let j = prev; j <= k; j++) {\n          arr[j] = value;\n        }\n        prev = k + 1;\n      }\n      for (let i = prev; i < 256; i++) {\n        arr[i] = arr[prev - 1];\n      }\n      return arr.join(\",\");\n    };\n    const id = `g_${this.#docId}_hcm_${filterName}_filter`;\n    const filter = info.filter = this.#createFilter(id);\n    this.#addGrayConversion(filter);\n    this.#addTransferMapConversion(getSteps(newFgRGB[0], newBgRGB[0], 5), getSteps(newFgRGB[1], newBgRGB[1], 5), getSteps(newFgRGB[2], newBgRGB[2], 5), filter);\n    info.url = `url(#${id})`;\n    return info.url;\n  }\n  destroy(keepHCM = false) {\n    if (keepHCM && this.#hcmCache.size !== 0) {\n      return;\n    }\n    if (this.#_defs) {\n      this.#_defs.parentNode.parentNode.remove();\n      this.#_defs = null;\n    }\n    if (this.#_cache) {\n      this.#_cache.clear();\n      this.#_cache = null;\n    }\n    this.#id = 0;\n  }\n  #addGrayConversion(filter) {\n    const feColorMatrix = this.#document.createElementNS(SVG_NS, \"feColorMatrix\");\n    feColorMatrix.setAttribute(\"type\", \"matrix\");\n    feColorMatrix.setAttribute(\"values\", \"0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 1 0\");\n    filter.append(feColorMatrix);\n  }\n  #createFilter(id) {\n    const filter = this.#document.createElementNS(SVG_NS, \"filter\");\n    filter.setAttribute(\"color-interpolation-filters\", \"sRGB\");\n    filter.setAttribute(\"id\", id);\n    this.#defs.append(filter);\n    return filter;\n  }\n  #appendFeFunc(feComponentTransfer, func, table) {\n    const feFunc = this.#document.createElementNS(SVG_NS, func);\n    feFunc.setAttribute(\"type\", \"discrete\");\n    feFunc.setAttribute(\"tableValues\", table);\n    feComponentTransfer.append(feFunc);\n  }\n  #addTransferMapConversion(rTable, gTable, bTable, filter) {\n    const feComponentTransfer = this.#document.createElementNS(SVG_NS, \"feComponentTransfer\");\n    filter.append(feComponentTransfer);\n    this.#appendFeFunc(feComponentTransfer, \"feFuncR\", rTable);\n    this.#appendFeFunc(feComponentTransfer, \"feFuncG\", gTable);\n    this.#appendFeFunc(feComponentTransfer, \"feFuncB\", bTable);\n  }\n  #getRGB(color) {\n    this.#defs.style.color = color;\n    return getRGB(getComputedStyle(this.#defs).getPropertyValue(\"color\"));\n  }\n}\nclass DOMCanvasFactory extends _base_factory_js__WEBPACK_IMPORTED_MODULE_0__.BaseCanvasFactory {\n  constructor({\n    ownerDocument = globalThis.document\n  } = {}) {\n    super();\n    this._document = ownerDocument;\n  }\n  _createCanvas(width, height) {\n    const canvas = this._document.createElement(\"canvas\");\n    canvas.width = width;\n    canvas.height = height;\n    return canvas;\n  }\n}\nasync function fetchData(url, type = \"text\") {\n  if (isValidFetchUrl(url, document.baseURI)) {\n    const response = await fetch(url);\n    if (!response.ok) {\n      throw new Error(response.statusText);\n    }\n    switch (type) {\n      case \"arraybuffer\":\n        return response.arrayBuffer();\n      case \"blob\":\n        return response.blob();\n      case \"json\":\n        return response.json();\n    }\n    return response.text();\n  }\n  return new Promise((resolve, reject) => {\n    const request = new XMLHttpRequest();\n    request.open(\"GET\", url, true);\n    request.responseType = type;\n    request.onreadystatechange = () => {\n      if (request.readyState !== XMLHttpRequest.DONE) {\n        return;\n      }\n      if (request.status === 200 || request.status === 0) {\n        switch (type) {\n          case \"arraybuffer\":\n          case \"blob\":\n          case \"json\":\n            resolve(request.response);\n            return;\n        }\n        resolve(request.responseText);\n        return;\n      }\n      reject(new Error(request.statusText));\n    };\n    request.send(null);\n  });\n}\nclass DOMCMapReaderFactory extends _base_factory_js__WEBPACK_IMPORTED_MODULE_0__.BaseCMapReaderFactory {\n  _fetchData(url, compressionType) {\n    return fetchData(url, this.isCompressed ? \"arraybuffer\" : \"text\").then(data => ({\n      cMapData: data instanceof ArrayBuffer ? new Uint8Array(data) : (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_1__.stringToBytes)(data),\n      compressionType\n    }));\n  }\n}\nclass DOMStandardFontDataFactory extends _base_factory_js__WEBPACK_IMPORTED_MODULE_0__.BaseStandardFontDataFactory {\n  _fetchData(url) {\n    return fetchData(url, \"arraybuffer\").then(data => new Uint8Array(data));\n  }\n}\nclass DOMSVGFactory extends _base_factory_js__WEBPACK_IMPORTED_MODULE_0__.BaseSVGFactory {\n  _createSVG(type) {\n    return document.createElementNS(SVG_NS, type);\n  }\n}\nclass PageViewport {\n  constructor({\n    viewBox,\n    scale,\n    rotation,\n    offsetX = 0,\n    offsetY = 0,\n    dontFlip = false\n  }) {\n    this.viewBox = viewBox;\n    this.scale = scale;\n    this.rotation = rotation;\n    this.offsetX = offsetX;\n    this.offsetY = offsetY;\n    const centerX = (viewBox[2] + viewBox[0]) / 2;\n    const centerY = (viewBox[3] + viewBox[1]) / 2;\n    let rotateA, rotateB, rotateC, rotateD;\n    rotation %= 360;\n    if (rotation < 0) {\n      rotation += 360;\n    }\n    switch (rotation) {\n      case 180:\n        rotateA = -1;\n        rotateB = 0;\n        rotateC = 0;\n        rotateD = 1;\n        break;\n      case 90:\n        rotateA = 0;\n        rotateB = 1;\n        rotateC = 1;\n        rotateD = 0;\n        break;\n      case 270:\n        rotateA = 0;\n        rotateB = -1;\n        rotateC = -1;\n        rotateD = 0;\n        break;\n      case 0:\n        rotateA = 1;\n        rotateB = 0;\n        rotateC = 0;\n        rotateD = -1;\n        break;\n      default:\n        throw new Error(\"PageViewport: Invalid rotation, must be a multiple of 90 degrees.\");\n    }\n    if (dontFlip) {\n      rotateC = -rotateC;\n      rotateD = -rotateD;\n    }\n    let offsetCanvasX, offsetCanvasY;\n    let width, height;\n    if (rotateA === 0) {\n      offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX;\n      offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY;\n      width = (viewBox[3] - viewBox[1]) * scale;\n      height = (viewBox[2] - viewBox[0]) * scale;\n    } else {\n      offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX;\n      offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY;\n      width = (viewBox[2] - viewBox[0]) * scale;\n      height = (viewBox[3] - viewBox[1]) * scale;\n    }\n    this.transform = [rotateA * scale, rotateB * scale, rotateC * scale, rotateD * scale, offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY, offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY];\n    this.width = width;\n    this.height = height;\n  }\n  get rawDims() {\n    const {\n      viewBox\n    } = this;\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, \"rawDims\", {\n      pageWidth: viewBox[2] - viewBox[0],\n      pageHeight: viewBox[3] - viewBox[1],\n      pageX: viewBox[0],\n      pageY: viewBox[1]\n    });\n  }\n  clone({\n    scale = this.scale,\n    rotation = this.rotation,\n    offsetX = this.offsetX,\n    offsetY = this.offsetY,\n    dontFlip = false\n  } = {}) {\n    return new PageViewport({\n      viewBox: this.viewBox.slice(),\n      scale,\n      rotation,\n      offsetX,\n      offsetY,\n      dontFlip\n    });\n  }\n  convertToViewportPoint(x, y) {\n    return _shared_util_js__WEBPACK_IMPORTED_MODULE_1__.Util.applyTransform([x, y], this.transform);\n  }\n  convertToViewportRectangle(rect) {\n    const topLeft = _shared_util_js__WEBPACK_IMPORTED_MODULE_1__.Util.applyTransform([rect[0], rect[1]], this.transform);\n    const bottomRight = _shared_util_js__WEBPACK_IMPORTED_MODULE_1__.Util.applyTransform([rect[2], rect[3]], this.transform);\n    return [topLeft[0], topLeft[1], bottomRight[0], bottomRight[1]];\n  }\n  convertToPdfPoint(x, y) {\n    return _shared_util_js__WEBPACK_IMPORTED_MODULE_1__.Util.applyInverseTransform([x, y], this.transform);\n  }\n}\nclass RenderingCancelledException extends _shared_util_js__WEBPACK_IMPORTED_MODULE_1__.BaseException {\n  constructor(msg, extraDelay = 0) {\n    super(msg, \"RenderingCancelledException\");\n    this.extraDelay = extraDelay;\n  }\n}\nfunction isDataScheme(url) {\n  const ii = url.length;\n  let i = 0;\n  while (i < ii && url[i].trim() === \"\") {\n    i++;\n  }\n  return url.substring(i, i + 5).toLowerCase() === \"data:\";\n}\nfunction isPdfFile(filename) {\n  return typeof filename === \"string\" && /\\.pdf$/i.test(filename);\n}\nfunction getFilenameFromUrl(url, onlyStripPath = false) {\n  if (!onlyStripPath) {\n    [url] = url.split(/[#?]/, 1);\n  }\n  return url.substring(url.lastIndexOf(\"/\") + 1);\n}\nfunction getPdfFilenameFromUrl(url, defaultFilename = \"document.pdf\") {\n  if (typeof url !== \"string\") {\n    return defaultFilename;\n  }\n  if (isDataScheme(url)) {\n    (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_1__.warn)('getPdfFilenameFromUrl: ignore \"data:\"-URL for performance reasons.');\n    return defaultFilename;\n  }\n  const reURI = /^(?:(?:[^:]+:)?\\/\\/[^/]+)?([^?#]*)(\\?[^#]*)?(#.*)?$/;\n  const reFilename = /[^/?#=]+\\.pdf\\b(?!.*\\.pdf\\b)/i;\n  const splitURI = reURI.exec(url);\n  let suggestedFilename = reFilename.exec(splitURI[1]) || reFilename.exec(splitURI[2]) || reFilename.exec(splitURI[3]);\n  if (suggestedFilename) {\n    suggestedFilename = suggestedFilename[0];\n    if (suggestedFilename.includes(\"%\")) {\n      try {\n        suggestedFilename = reFilename.exec(decodeURIComponent(suggestedFilename))[0];\n      } catch {}\n    }\n  }\n  return suggestedFilename || defaultFilename;\n}\nclass StatTimer {\n  started = Object.create(null);\n  times = [];\n  time(name) {\n    if (name in this.started) {\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_1__.warn)(`Timer is already running for ${name}`);\n    }\n    this.started[name] = Date.now();\n  }\n  timeEnd(name) {\n    if (!(name in this.started)) {\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_1__.warn)(`Timer has not been started for ${name}`);\n    }\n    this.times.push({\n      name,\n      start: this.started[name],\n      end: Date.now()\n    });\n    delete this.started[name];\n  }\n  toString() {\n    const outBuf = [];\n    let longest = 0;\n    for (const {\n      name\n    } of this.times) {\n      longest = Math.max(name.length, longest);\n    }\n    for (const {\n      name,\n      start,\n      end\n    } of this.times) {\n      outBuf.push(`${name.padEnd(longest)} ${end - start}ms\\n`);\n    }\n    return outBuf.join(\"\");\n  }\n}\nfunction isValidFetchUrl(url, baseUrl) {\n  try {\n    const {\n      protocol\n    } = baseUrl ? new URL(url, baseUrl) : new URL(url);\n    return protocol === \"http:\" || protocol === \"https:\";\n  } catch {\n    return false;\n  }\n}\nfunction noContextMenu(e) {\n  e.preventDefault();\n}\nfunction deprecated(details) {\n  console.error(\"Deprecated API usage: \" + details);\n}\nlet pdfDateStringRegex;\nclass PDFDateString {\n  static toDateObject(input) {\n    if (!input || typeof input !== \"string\") {\n      return null;\n    }\n    pdfDateStringRegex ||= new RegExp(\"^D:\" + \"(\\\\d{4})\" + \"(\\\\d{2})?\" + \"(\\\\d{2})?\" + \"(\\\\d{2})?\" + \"(\\\\d{2})?\" + \"(\\\\d{2})?\" + \"([Z|+|-])?\" + \"(\\\\d{2})?\" + \"'?\" + \"(\\\\d{2})?\" + \"'?\");\n    const matches = pdfDateStringRegex.exec(input);\n    if (!matches) {\n      return null;\n    }\n    const year = parseInt(matches[1], 10);\n    let month = parseInt(matches[2], 10);\n    month = month >= 1 && month <= 12 ? month - 1 : 0;\n    let day = parseInt(matches[3], 10);\n    day = day >= 1 && day <= 31 ? day : 1;\n    let hour = parseInt(matches[4], 10);\n    hour = hour >= 0 && hour <= 23 ? hour : 0;\n    let minute = parseInt(matches[5], 10);\n    minute = minute >= 0 && minute <= 59 ? minute : 0;\n    let second = parseInt(matches[6], 10);\n    second = second >= 0 && second <= 59 ? second : 0;\n    const universalTimeRelation = matches[7] || \"Z\";\n    let offsetHour = parseInt(matches[8], 10);\n    offsetHour = offsetHour >= 0 && offsetHour <= 23 ? offsetHour : 0;\n    let offsetMinute = parseInt(matches[9], 10) || 0;\n    offsetMinute = offsetMinute >= 0 && offsetMinute <= 59 ? offsetMinute : 0;\n    if (universalTimeRelation === \"-\") {\n      hour += offsetHour;\n      minute += offsetMinute;\n    } else if (universalTimeRelation === \"+\") {\n      hour -= offsetHour;\n      minute -= offsetMinute;\n    }\n    return new Date(Date.UTC(year, month, day, hour, minute, second));\n  }\n}\nfunction getXfaPageViewport(xfaPage, {\n  scale = 1,\n  rotation = 0\n}) {\n  const {\n    width,\n    height\n  } = xfaPage.attributes.style;\n  const viewBox = [0, 0, parseInt(width), parseInt(height)];\n  return new PageViewport({\n    viewBox,\n    scale,\n    rotation\n  });\n}\nfunction getRGB(color) {\n  if (color.startsWith(\"#\")) {\n    const colorRGB = parseInt(color.slice(1), 16);\n    return [(colorRGB & 0xff0000) >> 16, (colorRGB & 0x00ff00) >> 8, colorRGB & 0x0000ff];\n  }\n  if (color.startsWith(\"rgb(\")) {\n    return color.slice(4, -1).split(\",\").map(x => parseInt(x));\n  }\n  if (color.startsWith(\"rgba(\")) {\n    return color.slice(5, -1).split(\",\").map(x => parseInt(x)).slice(0, 3);\n  }\n  (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_1__.warn)(`Not a valid color format: \"${color}\"`);\n  return [0, 0, 0];\n}\nfunction getColorValues(colors) {\n  const span = document.createElement(\"span\");\n  span.style.visibility = \"hidden\";\n  document.body.append(span);\n  for (const name of colors.keys()) {\n    span.style.color = name;\n    const computedColor = window.getComputedStyle(span).color;\n    colors.set(name, getRGB(computedColor));\n  }\n  span.remove();\n}\nfunction getCurrentTransform(ctx) {\n  const {\n    a,\n    b,\n    c,\n    d,\n    e,\n    f\n  } = ctx.getTransform();\n  return [a, b, c, d, e, f];\n}\nfunction getCurrentTransformInverse(ctx) {\n  const {\n    a,\n    b,\n    c,\n    d,\n    e,\n    f\n  } = ctx.getTransform().invertSelf();\n  return [a, b, c, d, e, f];\n}\nfunction setLayerDimensions(div, viewport, mustFlip = false, mustRotate = true) {\n  if (viewport instanceof PageViewport) {\n    const {\n      pageWidth,\n      pageHeight\n    } = viewport.rawDims;\n    const {\n      style\n    } = div;\n    const useRound = _shared_util_js__WEBPACK_IMPORTED_MODULE_1__.FeatureTest.isCSSRoundSupported;\n    const w = `var(--scale-factor) * ${pageWidth}px`,\n      h = `var(--scale-factor) * ${pageHeight}px`;\n    const widthStr = useRound ? `round(${w}, 1px)` : `calc(${w})`,\n      heightStr = useRound ? `round(${h}, 1px)` : `calc(${h})`;\n    if (!mustFlip || viewport.rotation % 180 === 0) {\n      style.width = widthStr;\n      style.height = heightStr;\n    } else {\n      style.width = heightStr;\n      style.height = widthStr;\n    }\n  }\n  if (mustRotate) {\n    div.setAttribute(\"data-main-rotation\", viewport.rotation);\n  }\n}\n\n\n/***/ }),\n\n/***/ 457:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   PDFNetworkStream: () => (/* binding */ PDFNetworkStream)\n/* harmony export */ });\n/* harmony import */ var _shared_util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(292);\n/* harmony import */ var _network_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(490);\n\n\nconst OK_RESPONSE = 200;\nconst PARTIAL_CONTENT_RESPONSE = 206;\nfunction getArrayBuffer(xhr) {\n  const data = xhr.response;\n  if (typeof data !== \"string\") {\n    return data;\n  }\n  return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.stringToBytes)(data).buffer;\n}\nclass NetworkManager {\n  constructor(url, args = {}) {\n    this.url = url;\n    this.isHttp = /^https?:/i.test(url);\n    this.httpHeaders = this.isHttp && args.httpHeaders || Object.create(null);\n    this.withCredentials = args.withCredentials || false;\n    this.currXhrId = 0;\n    this.pendingRequests = Object.create(null);\n  }\n  requestRange(begin, end, listeners) {\n    const args = {\n      begin,\n      end\n    };\n    for (const prop in listeners) {\n      args[prop] = listeners[prop];\n    }\n    return this.request(args);\n  }\n  requestFull(listeners) {\n    return this.request(listeners);\n  }\n  request(args) {\n    const xhr = new XMLHttpRequest();\n    const xhrId = this.currXhrId++;\n    const pendingRequest = this.pendingRequests[xhrId] = {\n      xhr\n    };\n    xhr.open(\"GET\", this.url);\n    xhr.withCredentials = this.withCredentials;\n    for (const property in this.httpHeaders) {\n      const value = this.httpHeaders[property];\n      if (value === undefined) {\n        continue;\n      }\n      xhr.setRequestHeader(property, value);\n    }\n    if (this.isHttp && \"begin\" in args && \"end\" in args) {\n      xhr.setRequestHeader(\"Range\", `bytes=${args.begin}-${args.end - 1}`);\n      pendingRequest.expectedStatus = PARTIAL_CONTENT_RESPONSE;\n    } else {\n      pendingRequest.expectedStatus = OK_RESPONSE;\n    }\n    xhr.responseType = \"arraybuffer\";\n    if (args.onError) {\n      xhr.onerror = function (evt) {\n        args.onError(xhr.status);\n      };\n    }\n    xhr.onreadystatechange = this.onStateChange.bind(this, xhrId);\n    xhr.onprogress = this.onProgress.bind(this, xhrId);\n    pendingRequest.onHeadersReceived = args.onHeadersReceived;\n    pendingRequest.onDone = args.onDone;\n    pendingRequest.onError = args.onError;\n    pendingRequest.onProgress = args.onProgress;\n    xhr.send(null);\n    return xhrId;\n  }\n  onProgress(xhrId, evt) {\n    const pendingRequest = this.pendingRequests[xhrId];\n    if (!pendingRequest) {\n      return;\n    }\n    pendingRequest.onProgress?.(evt);\n  }\n  onStateChange(xhrId, evt) {\n    const pendingRequest = this.pendingRequests[xhrId];\n    if (!pendingRequest) {\n      return;\n    }\n    const xhr = pendingRequest.xhr;\n    if (xhr.readyState >= 2 && pendingRequest.onHeadersReceived) {\n      pendingRequest.onHeadersReceived();\n      delete pendingRequest.onHeadersReceived;\n    }\n    if (xhr.readyState !== 4) {\n      return;\n    }\n    if (!(xhrId in this.pendingRequests)) {\n      return;\n    }\n    delete this.pendingRequests[xhrId];\n    if (xhr.status === 0 && this.isHttp) {\n      pendingRequest.onError?.(xhr.status);\n      return;\n    }\n    const xhrStatus = xhr.status || OK_RESPONSE;\n    const ok_response_on_range_request = xhrStatus === OK_RESPONSE && pendingRequest.expectedStatus === PARTIAL_CONTENT_RESPONSE;\n    if (!ok_response_on_range_request && xhrStatus !== pendingRequest.expectedStatus) {\n      pendingRequest.onError?.(xhr.status);\n      return;\n    }\n    const chunk = getArrayBuffer(xhr);\n    if (xhrStatus === PARTIAL_CONTENT_RESPONSE) {\n      const rangeHeader = xhr.getResponseHeader(\"Content-Range\");\n      const matches = /bytes (\\d+)-(\\d+)\\/(\\d+)/.exec(rangeHeader);\n      pendingRequest.onDone({\n        begin: parseInt(matches[1], 10),\n        chunk\n      });\n    } else if (chunk) {\n      pendingRequest.onDone({\n        begin: 0,\n        chunk\n      });\n    } else {\n      pendingRequest.onError?.(xhr.status);\n    }\n  }\n  getRequestXhr(xhrId) {\n    return this.pendingRequests[xhrId].xhr;\n  }\n  isPendingRequest(xhrId) {\n    return xhrId in this.pendingRequests;\n  }\n  abortRequest(xhrId) {\n    const xhr = this.pendingRequests[xhrId].xhr;\n    delete this.pendingRequests[xhrId];\n    xhr.abort();\n  }\n}\nclass PDFNetworkStream {\n  constructor(source) {\n    this._source = source;\n    this._manager = new NetworkManager(source.url, {\n      httpHeaders: source.httpHeaders,\n      withCredentials: source.withCredentials\n    });\n    this._rangeChunkSize = source.rangeChunkSize;\n    this._fullRequestReader = null;\n    this._rangeRequestReaders = [];\n  }\n  _onRangeRequestReaderClosed(reader) {\n    const i = this._rangeRequestReaders.indexOf(reader);\n    if (i >= 0) {\n      this._rangeRequestReaders.splice(i, 1);\n    }\n  }\n  getFullReader() {\n    (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.assert)(!this._fullRequestReader, \"PDFNetworkStream.getFullReader can only be called once.\");\n    this._fullRequestReader = new PDFNetworkStreamFullRequestReader(this._manager, this._source);\n    return this._fullRequestReader;\n  }\n  getRangeReader(begin, end) {\n    const reader = new PDFNetworkStreamRangeRequestReader(this._manager, begin, end);\n    reader.onClosed = this._onRangeRequestReaderClosed.bind(this);\n    this._rangeRequestReaders.push(reader);\n    return reader;\n  }\n  cancelAllRequests(reason) {\n    this._fullRequestReader?.cancel(reason);\n    for (const reader of this._rangeRequestReaders.slice(0)) {\n      reader.cancel(reason);\n    }\n  }\n}\nclass PDFNetworkStreamFullRequestReader {\n  constructor(manager, source) {\n    this._manager = manager;\n    const args = {\n      onHeadersReceived: this._onHeadersReceived.bind(this),\n      onDone: this._onDone.bind(this),\n      onError: this._onError.bind(this),\n      onProgress: this._onProgress.bind(this)\n    };\n    this._url = source.url;\n    this._fullRequestId = manager.requestFull(args);\n    this._headersReceivedCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n    this._disableRange = source.disableRange || false;\n    this._contentLength = source.length;\n    this._rangeChunkSize = source.rangeChunkSize;\n    if (!this._rangeChunkSize && !this._disableRange) {\n      this._disableRange = true;\n    }\n    this._isStreamingSupported = false;\n    this._isRangeSupported = false;\n    this._cachedChunks = [];\n    this._requests = [];\n    this._done = false;\n    this._storedError = undefined;\n    this._filename = null;\n    this.onProgress = null;\n  }\n  _onHeadersReceived() {\n    const fullRequestXhrId = this._fullRequestId;\n    const fullRequestXhr = this._manager.getRequestXhr(fullRequestXhrId);\n    const getResponseHeader = name => fullRequestXhr.getResponseHeader(name);\n    const {\n      allowRangeRequests,\n      suggestedLength\n    } = (0,_network_utils_js__WEBPACK_IMPORTED_MODULE_1__.validateRangeRequestCapabilities)({\n      getResponseHeader,\n      isHttp: this._manager.isHttp,\n      rangeChunkSize: this._rangeChunkSize,\n      disableRange: this._disableRange\n    });\n    if (allowRangeRequests) {\n      this._isRangeSupported = true;\n    }\n    this._contentLength = suggestedLength || this._contentLength;\n    this._filename = (0,_network_utils_js__WEBPACK_IMPORTED_MODULE_1__.extractFilenameFromHeader)(getResponseHeader);\n    if (this._isRangeSupported) {\n      this._manager.abortRequest(fullRequestXhrId);\n    }\n    this._headersReceivedCapability.resolve();\n  }\n  _onDone(data) {\n    if (data) {\n      if (this._requests.length > 0) {\n        const requestCapability = this._requests.shift();\n        requestCapability.resolve({\n          value: data.chunk,\n          done: false\n        });\n      } else {\n        this._cachedChunks.push(data.chunk);\n      }\n    }\n    this._done = true;\n    if (this._cachedChunks.length > 0) {\n      return;\n    }\n    for (const requestCapability of this._requests) {\n      requestCapability.resolve({\n        value: undefined,\n        done: true\n      });\n    }\n    this._requests.length = 0;\n  }\n  _onError(status) {\n    this._storedError = (0,_network_utils_js__WEBPACK_IMPORTED_MODULE_1__.createResponseStatusError)(status, this._url);\n    this._headersReceivedCapability.reject(this._storedError);\n    for (const requestCapability of this._requests) {\n      requestCapability.reject(this._storedError);\n    }\n    this._requests.length = 0;\n    this._cachedChunks.length = 0;\n  }\n  _onProgress(evt) {\n    this.onProgress?.({\n      loaded: evt.loaded,\n      total: evt.lengthComputable ? evt.total : this._contentLength\n    });\n  }\n  get filename() {\n    return this._filename;\n  }\n  get isRangeSupported() {\n    return this._isRangeSupported;\n  }\n  get isStreamingSupported() {\n    return this._isStreamingSupported;\n  }\n  get contentLength() {\n    return this._contentLength;\n  }\n  get headersReady() {\n    return this._headersReceivedCapability.promise;\n  }\n  async read() {\n    if (this._storedError) {\n      throw this._storedError;\n    }\n    if (this._cachedChunks.length > 0) {\n      const chunk = this._cachedChunks.shift();\n      return {\n        value: chunk,\n        done: false\n      };\n    }\n    if (this._done) {\n      return {\n        value: undefined,\n        done: true\n      };\n    }\n    const requestCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n    this._requests.push(requestCapability);\n    return requestCapability.promise;\n  }\n  cancel(reason) {\n    this._done = true;\n    this._headersReceivedCapability.reject(reason);\n    for (const requestCapability of this._requests) {\n      requestCapability.resolve({\n        value: undefined,\n        done: true\n      });\n    }\n    this._requests.length = 0;\n    if (this._manager.isPendingRequest(this._fullRequestId)) {\n      this._manager.abortRequest(this._fullRequestId);\n    }\n    this._fullRequestReader = null;\n  }\n}\nclass PDFNetworkStreamRangeRequestReader {\n  constructor(manager, begin, end) {\n    this._manager = manager;\n    const args = {\n      onDone: this._onDone.bind(this),\n      onError: this._onError.bind(this),\n      onProgress: this._onProgress.bind(this)\n    };\n    this._url = manager.url;\n    this._requestId = manager.requestRange(begin, end, args);\n    this._requests = [];\n    this._queuedChunk = null;\n    this._done = false;\n    this._storedError = undefined;\n    this.onProgress = null;\n    this.onClosed = null;\n  }\n  _close() {\n    this.onClosed?.(this);\n  }\n  _onDone(data) {\n    const chunk = data.chunk;\n    if (this._requests.length > 0) {\n      const requestCapability = this._requests.shift();\n      requestCapability.resolve({\n        value: chunk,\n        done: false\n      });\n    } else {\n      this._queuedChunk = chunk;\n    }\n    this._done = true;\n    for (const requestCapability of this._requests) {\n      requestCapability.resolve({\n        value: undefined,\n        done: true\n      });\n    }\n    this._requests.length = 0;\n    this._close();\n  }\n  _onError(status) {\n    this._storedError = (0,_network_utils_js__WEBPACK_IMPORTED_MODULE_1__.createResponseStatusError)(status, this._url);\n    for (const requestCapability of this._requests) {\n      requestCapability.reject(this._storedError);\n    }\n    this._requests.length = 0;\n    this._queuedChunk = null;\n  }\n  _onProgress(evt) {\n    if (!this.isStreamingSupported) {\n      this.onProgress?.({\n        loaded: evt.loaded\n      });\n    }\n  }\n  get isStreamingSupported() {\n    return false;\n  }\n  async read() {\n    if (this._storedError) {\n      throw this._storedError;\n    }\n    if (this._queuedChunk !== null) {\n      const chunk = this._queuedChunk;\n      this._queuedChunk = null;\n      return {\n        value: chunk,\n        done: false\n      };\n    }\n    if (this._done) {\n      return {\n        value: undefined,\n        done: true\n      };\n    }\n    const requestCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n    this._requests.push(requestCapability);\n    return requestCapability.promise;\n  }\n  cancel(reason) {\n    this._done = true;\n    for (const requestCapability of this._requests) {\n      requestCapability.resolve({\n        value: undefined,\n        done: true\n      });\n    }\n    this._requests.length = 0;\n    if (this._manager.isPendingRequest(this._requestId)) {\n      this._manager.abortRequest(this._requestId);\n    }\n    this._close();\n  }\n}\n\n\n/***/ }),\n\n/***/ 490:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n  createResponseStatusError: () => (/* binding */ createResponseStatusError),\n  extractFilenameFromHeader: () => (/* binding */ extractFilenameFromHeader),\n  validateRangeRequestCapabilities: () => (/* binding */ validateRangeRequestCapabilities),\n  validateResponseStatus: () => (/* binding */ validateResponseStatus)\n});\n\n// EXTERNAL MODULE: ./src/shared/util.js\nvar util = __webpack_require__(292);\n;// ./src/display/content_disposition.js\n\nfunction getFilenameFromContentDispositionHeader(contentDisposition) {\n  let needsEncodingFixup = true;\n  let tmp = toParamRegExp(\"filename\\\\*\", \"i\").exec(contentDisposition);\n  if (tmp) {\n    tmp = tmp[1];\n    let filename = rfc2616unquote(tmp);\n    filename = unescape(filename);\n    filename = rfc5987decode(filename);\n    filename = rfc2047decode(filename);\n    return fixupEncoding(filename);\n  }\n  tmp = rfc2231getparam(contentDisposition);\n  if (tmp) {\n    const filename = rfc2047decode(tmp);\n    return fixupEncoding(filename);\n  }\n  tmp = toParamRegExp(\"filename\", \"i\").exec(contentDisposition);\n  if (tmp) {\n    tmp = tmp[1];\n    let filename = rfc2616unquote(tmp);\n    filename = rfc2047decode(filename);\n    return fixupEncoding(filename);\n  }\n  function toParamRegExp(attributePattern, flags) {\n    return new RegExp(\"(?:^|;)\\\\s*\" + attributePattern + \"\\\\s*=\\\\s*\" + \"(\" + '[^\";\\\\s][^;\\\\s]*' + \"|\" + '\"(?:[^\"\\\\\\\\]|\\\\\\\\\"?)+\"?' + \")\", flags);\n  }\n  function textdecode(encoding, value) {\n    if (encoding) {\n      if (!/^[\\x00-\\xFF]+$/.test(value)) {\n        return value;\n      }\n      try {\n        const decoder = new TextDecoder(encoding, {\n          fatal: true\n        });\n        const buffer = (0,util.stringToBytes)(value);\n        value = decoder.decode(buffer);\n        needsEncodingFixup = false;\n      } catch {}\n    }\n    return value;\n  }\n  function fixupEncoding(value) {\n    if (needsEncodingFixup && /[\\x80-\\xff]/.test(value)) {\n      value = textdecode(\"utf-8\", value);\n      if (needsEncodingFixup) {\n        value = textdecode(\"iso-8859-1\", value);\n      }\n    }\n    return value;\n  }\n  function rfc2231getparam(contentDispositionStr) {\n    const matches = [];\n    let match;\n    const iter = toParamRegExp(\"filename\\\\*((?!0\\\\d)\\\\d+)(\\\\*?)\", \"ig\");\n    while ((match = iter.exec(contentDispositionStr)) !== null) {\n      let [, n, quot, part] = match;\n      n = parseInt(n, 10);\n      if (n in matches) {\n        if (n === 0) {\n          break;\n        }\n        continue;\n      }\n      matches[n] = [quot, part];\n    }\n    const parts = [];\n    for (let n = 0; n < matches.length; ++n) {\n      if (!(n in matches)) {\n        break;\n      }\n      let [quot, part] = matches[n];\n      part = rfc2616unquote(part);\n      if (quot) {\n        part = unescape(part);\n        if (n === 0) {\n          part = rfc5987decode(part);\n        }\n      }\n      parts.push(part);\n    }\n    return parts.join(\"\");\n  }\n  function rfc2616unquote(value) {\n    if (value.startsWith('\"')) {\n      const parts = value.slice(1).split('\\\\\"');\n      for (let i = 0; i < parts.length; ++i) {\n        const quotindex = parts[i].indexOf('\"');\n        if (quotindex !== -1) {\n          parts[i] = parts[i].slice(0, quotindex);\n          parts.length = i + 1;\n        }\n        parts[i] = parts[i].replaceAll(/\\\\(.)/g, \"$1\");\n      }\n      value = parts.join('\"');\n    }\n    return value;\n  }\n  function rfc5987decode(extvalue) {\n    const encodingend = extvalue.indexOf(\"'\");\n    if (encodingend === -1) {\n      return extvalue;\n    }\n    const encoding = extvalue.slice(0, encodingend);\n    const langvalue = extvalue.slice(encodingend + 1);\n    const value = langvalue.replace(/^[^']*'/, \"\");\n    return textdecode(encoding, value);\n  }\n  function rfc2047decode(value) {\n    if (!value.startsWith(\"=?\") || /[\\x00-\\x19\\x80-\\xff]/.test(value)) {\n      return value;\n    }\n    return value.replaceAll(/=\\?([\\w-]*)\\?([QqBb])\\?((?:[^?]|\\?(?!=))*)\\?=/g, function (matches, charset, encoding, text) {\n      if (encoding === \"q\" || encoding === \"Q\") {\n        text = text.replaceAll(\"_\", \" \");\n        text = text.replaceAll(/=([0-9a-fA-F]{2})/g, function (match, hex) {\n          return String.fromCharCode(parseInt(hex, 16));\n        });\n        return textdecode(charset, text);\n      }\n      try {\n        text = atob(text);\n      } catch {}\n      return textdecode(charset, text);\n    });\n  }\n  return \"\";\n}\n\n// EXTERNAL MODULE: ./src/display/display_utils.js\nvar display_utils = __webpack_require__(419);\n;// ./src/display/network_utils.js\n\n\n\nfunction validateRangeRequestCapabilities({\n  getResponseHeader,\n  isHttp,\n  rangeChunkSize,\n  disableRange\n}) {\n  const returnValues = {\n    allowRangeRequests: false,\n    suggestedLength: undefined\n  };\n  const length = parseInt(getResponseHeader(\"Content-Length\"), 10);\n  if (!Number.isInteger(length)) {\n    return returnValues;\n  }\n  returnValues.suggestedLength = length;\n  if (length <= 2 * rangeChunkSize) {\n    return returnValues;\n  }\n  if (disableRange || !isHttp) {\n    return returnValues;\n  }\n  if (getResponseHeader(\"Accept-Ranges\") !== \"bytes\") {\n    return returnValues;\n  }\n  const contentEncoding = getResponseHeader(\"Content-Encoding\") || \"identity\";\n  if (contentEncoding !== \"identity\") {\n    return returnValues;\n  }\n  returnValues.allowRangeRequests = true;\n  return returnValues;\n}\nfunction extractFilenameFromHeader(getResponseHeader) {\n  const contentDisposition = getResponseHeader(\"Content-Disposition\");\n  if (contentDisposition) {\n    let filename = getFilenameFromContentDispositionHeader(contentDisposition);\n    if (filename.includes(\"%\")) {\n      try {\n        filename = decodeURIComponent(filename);\n      } catch {}\n    }\n    if ((0,display_utils.isPdfFile)(filename)) {\n      return filename;\n    }\n  }\n  return null;\n}\nfunction createResponseStatusError(status, url) {\n  if (status === 404 || status === 0 && url.startsWith(\"file:\")) {\n    return new util.MissingPDFException('Missing PDF \"' + url + '\".');\n  }\n  return new util.UnexpectedResponseException(`Unexpected server response (${status}) while retrieving PDF \"${url}\".`, status);\n}\nfunction validateResponseStatus(status) {\n  return status === 200 || status === 206;\n}\n\n\n/***/ }),\n\n/***/ 573:\n/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   NodeCMapReaderFactory: () => (/* binding */ NodeCMapReaderFactory),\n/* harmony export */   NodeCanvasFactory: () => (/* binding */ NodeCanvasFactory),\n/* harmony export */   NodeFilterFactory: () => (/* binding */ NodeFilterFactory),\n/* harmony export */   NodeStandardFontDataFactory: () => (/* binding */ NodeStandardFontDataFactory)\n/* harmony export */ });\n/* harmony import */ var _base_factory_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(583);\n/* harmony import */ var _shared_util_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(292);\n\n\nlet fs, canvas, path2d_polyfill;\nif (_shared_util_js__WEBPACK_IMPORTED_MODULE_1__.isNodeJS) {\n  fs = await import(/*webpackIgnore: true*/\"fs\");\n  try {\n    canvas = await import(/*webpackIgnore: true*/\"canvas\");\n  } catch {}\n  try {\n    path2d_polyfill = await import(/*webpackIgnore: true*/\"path2d-polyfill\");\n  } catch {}\n}\nconst fetchData = function (url) {\n  return fs.promises.readFile(url).then(data => new Uint8Array(data));\n};\nclass NodeFilterFactory extends _base_factory_js__WEBPACK_IMPORTED_MODULE_0__.BaseFilterFactory {}\nclass NodeCanvasFactory extends _base_factory_js__WEBPACK_IMPORTED_MODULE_0__.BaseCanvasFactory {\n  _createCanvas(width, height) {\n    return canvas.createCanvas(width, height);\n  }\n}\nclass NodeCMapReaderFactory extends _base_factory_js__WEBPACK_IMPORTED_MODULE_0__.BaseCMapReaderFactory {\n  _fetchData(url, compressionType) {\n    return fetchData(url).then(data => ({\n      cMapData: data,\n      compressionType\n    }));\n  }\n}\nclass NodeStandardFontDataFactory extends _base_factory_js__WEBPACK_IMPORTED_MODULE_0__.BaseStandardFontDataFactory {\n  _fetchData(url) {\n    return fetchData(url);\n  }\n}\n\n__webpack_async_result__();\n} catch(e) { __webpack_async_result__(e); } }, 1);\n\n/***/ }),\n\n/***/ 583:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   BaseCMapReaderFactory: () => (/* binding */ BaseCMapReaderFactory),\n/* harmony export */   BaseCanvasFactory: () => (/* binding */ BaseCanvasFactory),\n/* harmony export */   BaseFilterFactory: () => (/* binding */ BaseFilterFactory),\n/* harmony export */   BaseSVGFactory: () => (/* binding */ BaseSVGFactory),\n/* harmony export */   BaseStandardFontDataFactory: () => (/* binding */ BaseStandardFontDataFactory)\n/* harmony export */ });\n/* harmony import */ var _shared_util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(292);\n\nclass BaseFilterFactory {\n  constructor() {\n    if (this.constructor === BaseFilterFactory) {\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.unreachable)(\"Cannot initialize BaseFilterFactory.\");\n    }\n  }\n  addFilter(maps) {\n    return \"none\";\n  }\n  addHCMFilter(fgColor, bgColor) {\n    return \"none\";\n  }\n  addHighlightHCMFilter(filterName, fgColor, bgColor, newFgColor, newBgColor) {\n    return \"none\";\n  }\n  destroy(keepHCM = false) {}\n}\nclass BaseCanvasFactory {\n  constructor() {\n    if (this.constructor === BaseCanvasFactory) {\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.unreachable)(\"Cannot initialize BaseCanvasFactory.\");\n    }\n  }\n  create(width, height) {\n    if (width <= 0 || height <= 0) {\n      throw new Error(\"Invalid canvas size\");\n    }\n    const canvas = this._createCanvas(width, height);\n    return {\n      canvas,\n      context: canvas.getContext(\"2d\")\n    };\n  }\n  reset(canvasAndContext, width, height) {\n    if (!canvasAndContext.canvas) {\n      throw new Error(\"Canvas is not specified\");\n    }\n    if (width <= 0 || height <= 0) {\n      throw new Error(\"Invalid canvas size\");\n    }\n    canvasAndContext.canvas.width = width;\n    canvasAndContext.canvas.height = height;\n  }\n  destroy(canvasAndContext) {\n    if (!canvasAndContext.canvas) {\n      throw new Error(\"Canvas is not specified\");\n    }\n    canvasAndContext.canvas.width = 0;\n    canvasAndContext.canvas.height = 0;\n    canvasAndContext.canvas = null;\n    canvasAndContext.context = null;\n  }\n  _createCanvas(width, height) {\n    (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.unreachable)(\"Abstract method `_createCanvas` called.\");\n  }\n}\nclass BaseCMapReaderFactory {\n  constructor({\n    baseUrl = null,\n    isCompressed = true\n  }) {\n    if (this.constructor === BaseCMapReaderFactory) {\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.unreachable)(\"Cannot initialize BaseCMapReaderFactory.\");\n    }\n    this.baseUrl = baseUrl;\n    this.isCompressed = isCompressed;\n  }\n  async fetch({\n    name\n  }) {\n    if (!this.baseUrl) {\n      throw new Error('The CMap \"baseUrl\" parameter must be specified, ensure that ' + 'the \"cMapUrl\" and \"cMapPacked\" API parameters are provided.');\n    }\n    if (!name) {\n      throw new Error(\"CMap name must be specified.\");\n    }\n    const url = this.baseUrl + name + (this.isCompressed ? \".bcmap\" : \"\");\n    const compressionType = this.isCompressed ? _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.CMapCompressionType.BINARY : _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.CMapCompressionType.NONE;\n    return this._fetchData(url, compressionType).catch(reason => {\n      throw new Error(`Unable to load ${this.isCompressed ? \"binary \" : \"\"}CMap at: ${url}`);\n    });\n  }\n  _fetchData(url, compressionType) {\n    (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.unreachable)(\"Abstract method `_fetchData` called.\");\n  }\n}\nclass BaseStandardFontDataFactory {\n  constructor({\n    baseUrl = null\n  }) {\n    if (this.constructor === BaseStandardFontDataFactory) {\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.unreachable)(\"Cannot initialize BaseStandardFontDataFactory.\");\n    }\n    this.baseUrl = baseUrl;\n  }\n  async fetch({\n    filename\n  }) {\n    if (!this.baseUrl) {\n      throw new Error('The standard font \"baseUrl\" parameter must be specified, ensure that ' + 'the \"standardFontDataUrl\" API parameter is provided.');\n    }\n    if (!filename) {\n      throw new Error(\"Font filename must be specified.\");\n    }\n    const url = `${this.baseUrl}${filename}`;\n    return this._fetchData(url).catch(reason => {\n      throw new Error(`Unable to load font data at: ${url}`);\n    });\n  }\n  _fetchData(url) {\n    (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.unreachable)(\"Abstract method `_fetchData` called.\");\n  }\n}\nclass BaseSVGFactory {\n  constructor() {\n    if (this.constructor === BaseSVGFactory) {\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.unreachable)(\"Cannot initialize BaseSVGFactory.\");\n    }\n  }\n  create(width, height, skipDimensions = false) {\n    if (width <= 0 || height <= 0) {\n      throw new Error(\"Invalid SVG dimensions\");\n    }\n    const svg = this._createSVG(\"svg:svg\");\n    svg.setAttribute(\"version\", \"1.1\");\n    if (!skipDimensions) {\n      svg.setAttribute(\"width\", `${width}px`);\n      svg.setAttribute(\"height\", `${height}px`);\n    }\n    svg.setAttribute(\"preserveAspectRatio\", \"none\");\n    svg.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n    return svg;\n  }\n  createElement(type) {\n    if (typeof type !== \"string\") {\n      throw new Error(\"Invalid SVG element type\");\n    }\n    return this._createSVG(type);\n  }\n  _createSVG(type) {\n    (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.unreachable)(\"Abstract method `_createSVG` called.\");\n  }\n}\n\n\n/***/ }),\n\n/***/ 585:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   PDFDataTransportStream: () => (/* binding */ PDFDataTransportStream)\n/* harmony export */ });\n/* harmony import */ var _shared_util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(292);\n/* harmony import */ var _display_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(419);\n\n\nclass PDFDataTransportStream {\n  constructor(pdfDataRangeTransport, {\n    disableRange = false,\n    disableStream = false\n  }) {\n    (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.assert)(pdfDataRangeTransport, 'PDFDataTransportStream - missing required \"pdfDataRangeTransport\" argument.');\n    const {\n      length,\n      initialData,\n      progressiveDone,\n      contentDispositionFilename\n    } = pdfDataRangeTransport;\n    this._queuedChunks = [];\n    this._progressiveDone = progressiveDone;\n    this._contentDispositionFilename = contentDispositionFilename;\n    if (initialData?.length > 0) {\n      const buffer = initialData instanceof Uint8Array && initialData.byteLength === initialData.buffer.byteLength ? initialData.buffer : new Uint8Array(initialData).buffer;\n      this._queuedChunks.push(buffer);\n    }\n    this._pdfDataRangeTransport = pdfDataRangeTransport;\n    this._isStreamingSupported = !disableStream;\n    this._isRangeSupported = !disableRange;\n    this._contentLength = length;\n    this._fullRequestReader = null;\n    this._rangeReaders = [];\n    pdfDataRangeTransport.addRangeListener((begin, chunk) => {\n      this._onReceiveData({\n        begin,\n        chunk\n      });\n    });\n    pdfDataRangeTransport.addProgressListener((loaded, total) => {\n      this._onProgress({\n        loaded,\n        total\n      });\n    });\n    pdfDataRangeTransport.addProgressiveReadListener(chunk => {\n      this._onReceiveData({\n        chunk\n      });\n    });\n    pdfDataRangeTransport.addProgressiveDoneListener(() => {\n      this._onProgressiveDone();\n    });\n    pdfDataRangeTransport.transportReady();\n  }\n  _onReceiveData({\n    begin,\n    chunk\n  }) {\n    const buffer = chunk instanceof Uint8Array && chunk.byteLength === chunk.buffer.byteLength ? chunk.buffer : new Uint8Array(chunk).buffer;\n    if (begin === undefined) {\n      if (this._fullRequestReader) {\n        this._fullRequestReader._enqueue(buffer);\n      } else {\n        this._queuedChunks.push(buffer);\n      }\n    } else {\n      const found = this._rangeReaders.some(function (rangeReader) {\n        if (rangeReader._begin !== begin) {\n          return false;\n        }\n        rangeReader._enqueue(buffer);\n        return true;\n      });\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.assert)(found, \"_onReceiveData - no `PDFDataTransportStreamRangeReader` instance found.\");\n    }\n  }\n  get _progressiveDataLength() {\n    return this._fullRequestReader?._loaded ?? 0;\n  }\n  _onProgress(evt) {\n    if (evt.total === undefined) {\n      this._rangeReaders[0]?.onProgress?.({\n        loaded: evt.loaded\n      });\n    } else {\n      this._fullRequestReader?.onProgress?.({\n        loaded: evt.loaded,\n        total: evt.total\n      });\n    }\n  }\n  _onProgressiveDone() {\n    this._fullRequestReader?.progressiveDone();\n    this._progressiveDone = true;\n  }\n  _removeRangeReader(reader) {\n    const i = this._rangeReaders.indexOf(reader);\n    if (i >= 0) {\n      this._rangeReaders.splice(i, 1);\n    }\n  }\n  getFullReader() {\n    (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.assert)(!this._fullRequestReader, \"PDFDataTransportStream.getFullReader can only be called once.\");\n    const queuedChunks = this._queuedChunks;\n    this._queuedChunks = null;\n    return new PDFDataTransportStreamReader(this, queuedChunks, this._progressiveDone, this._contentDispositionFilename);\n  }\n  getRangeReader(begin, end) {\n    if (end <= this._progressiveDataLength) {\n      return null;\n    }\n    const reader = new PDFDataTransportStreamRangeReader(this, begin, end);\n    this._pdfDataRangeTransport.requestDataRange(begin, end);\n    this._rangeReaders.push(reader);\n    return reader;\n  }\n  cancelAllRequests(reason) {\n    this._fullRequestReader?.cancel(reason);\n    for (const reader of this._rangeReaders.slice(0)) {\n      reader.cancel(reason);\n    }\n    this._pdfDataRangeTransport.abort();\n  }\n}\nclass PDFDataTransportStreamReader {\n  constructor(stream, queuedChunks, progressiveDone = false, contentDispositionFilename = null) {\n    this._stream = stream;\n    this._done = progressiveDone || false;\n    this._filename = (0,_display_utils_js__WEBPACK_IMPORTED_MODULE_1__.isPdfFile)(contentDispositionFilename) ? contentDispositionFilename : null;\n    this._queuedChunks = queuedChunks || [];\n    this._loaded = 0;\n    for (const chunk of this._queuedChunks) {\n      this._loaded += chunk.byteLength;\n    }\n    this._requests = [];\n    this._headersReady = Promise.resolve();\n    stream._fullRequestReader = this;\n    this.onProgress = null;\n  }\n  _enqueue(chunk) {\n    if (this._done) {\n      return;\n    }\n    if (this._requests.length > 0) {\n      const requestCapability = this._requests.shift();\n      requestCapability.resolve({\n        value: chunk,\n        done: false\n      });\n    } else {\n      this._queuedChunks.push(chunk);\n    }\n    this._loaded += chunk.byteLength;\n  }\n  get headersReady() {\n    return this._headersReady;\n  }\n  get filename() {\n    return this._filename;\n  }\n  get isRangeSupported() {\n    return this._stream._isRangeSupported;\n  }\n  get isStreamingSupported() {\n    return this._stream._isStreamingSupported;\n  }\n  get contentLength() {\n    return this._stream._contentLength;\n  }\n  async read() {\n    if (this._queuedChunks.length > 0) {\n      const chunk = this._queuedChunks.shift();\n      return {\n        value: chunk,\n        done: false\n      };\n    }\n    if (this._done) {\n      return {\n        value: undefined,\n        done: true\n      };\n    }\n    const requestCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n    this._requests.push(requestCapability);\n    return requestCapability.promise;\n  }\n  cancel(reason) {\n    this._done = true;\n    for (const requestCapability of this._requests) {\n      requestCapability.resolve({\n        value: undefined,\n        done: true\n      });\n    }\n    this._requests.length = 0;\n  }\n  progressiveDone() {\n    if (this._done) {\n      return;\n    }\n    this._done = true;\n  }\n}\nclass PDFDataTransportStreamRangeReader {\n  constructor(stream, begin, end) {\n    this._stream = stream;\n    this._begin = begin;\n    this._end = end;\n    this._queuedChunk = null;\n    this._requests = [];\n    this._done = false;\n    this.onProgress = null;\n  }\n  _enqueue(chunk) {\n    if (this._done) {\n      return;\n    }\n    if (this._requests.length === 0) {\n      this._queuedChunk = chunk;\n    } else {\n      const requestsCapability = this._requests.shift();\n      requestsCapability.resolve({\n        value: chunk,\n        done: false\n      });\n      for (const requestCapability of this._requests) {\n        requestCapability.resolve({\n          value: undefined,\n          done: true\n        });\n      }\n      this._requests.length = 0;\n    }\n    this._done = true;\n    this._stream._removeRangeReader(this);\n  }\n  get isStreamingSupported() {\n    return false;\n  }\n  async read() {\n    if (this._queuedChunk) {\n      const chunk = this._queuedChunk;\n      this._queuedChunk = null;\n      return {\n        value: chunk,\n        done: false\n      };\n    }\n    if (this._done) {\n      return {\n        value: undefined,\n        done: true\n      };\n    }\n    const requestCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n    this._requests.push(requestCapability);\n    return requestCapability.promise;\n  }\n  cancel(reason) {\n    this._done = true;\n    for (const requestCapability of this._requests) {\n      requestCapability.resolve({\n        value: undefined,\n        done: true\n      });\n    }\n    this._requests.length = 0;\n    this._stream._removeRangeReader(this);\n  }\n}\n\n\n/***/ }),\n\n/***/ 626:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   OptionalContentConfig: () => (/* binding */ OptionalContentConfig)\n/* harmony export */ });\n/* harmony import */ var _shared_util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(292);\n/* harmony import */ var _shared_murmurhash3_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(651);\n\n\nconst INTERNAL = Symbol(\"INTERNAL\");\nclass OptionalContentGroup {\n  #isDisplay = false;\n  #isPrint = false;\n  #userSet = false;\n  #visible = true;\n  constructor(renderingIntent, {\n    name,\n    intent,\n    usage\n  }) {\n    this.#isDisplay = !!(renderingIntent & _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.RenderingIntentFlag.DISPLAY);\n    this.#isPrint = !!(renderingIntent & _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.RenderingIntentFlag.PRINT);\n    this.name = name;\n    this.intent = intent;\n    this.usage = usage;\n  }\n  get visible() {\n    if (this.#userSet) {\n      return this.#visible;\n    }\n    if (!this.#visible) {\n      return false;\n    }\n    const {\n      print,\n      view\n    } = this.usage;\n    if (this.#isDisplay) {\n      return view?.viewState !== \"OFF\";\n    } else if (this.#isPrint) {\n      return print?.printState !== \"OFF\";\n    }\n    return true;\n  }\n  _setVisible(internal, visible, userSet = false) {\n    if (internal !== INTERNAL) {\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.unreachable)(\"Internal method `_setVisible` called.\");\n    }\n    this.#userSet = userSet;\n    this.#visible = visible;\n  }\n}\nclass OptionalContentConfig {\n  #cachedGetHash = null;\n  #groups = new Map();\n  #initialHash = null;\n  #order = null;\n  constructor(data, renderingIntent = _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.RenderingIntentFlag.DISPLAY) {\n    this.renderingIntent = renderingIntent;\n    this.name = null;\n    this.creator = null;\n    if (data === null) {\n      return;\n    }\n    this.name = data.name;\n    this.creator = data.creator;\n    this.#order = data.order;\n    for (const group of data.groups) {\n      this.#groups.set(group.id, new OptionalContentGroup(renderingIntent, group));\n    }\n    if (data.baseState === \"OFF\") {\n      for (const group of this.#groups.values()) {\n        group._setVisible(INTERNAL, false);\n      }\n    }\n    for (const on of data.on) {\n      this.#groups.get(on)._setVisible(INTERNAL, true);\n    }\n    for (const off of data.off) {\n      this.#groups.get(off)._setVisible(INTERNAL, false);\n    }\n    this.#initialHash = this.getHash();\n  }\n  #evaluateVisibilityExpression(array) {\n    const length = array.length;\n    if (length < 2) {\n      return true;\n    }\n    const operator = array[0];\n    for (let i = 1; i < length; i++) {\n      const element = array[i];\n      let state;\n      if (Array.isArray(element)) {\n        state = this.#evaluateVisibilityExpression(element);\n      } else if (this.#groups.has(element)) {\n        state = this.#groups.get(element).visible;\n      } else {\n        (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(`Optional content group not found: ${element}`);\n        return true;\n      }\n      switch (operator) {\n        case \"And\":\n          if (!state) {\n            return false;\n          }\n          break;\n        case \"Or\":\n          if (state) {\n            return true;\n          }\n          break;\n        case \"Not\":\n          return !state;\n        default:\n          return true;\n      }\n    }\n    return operator === \"And\";\n  }\n  isVisible(group) {\n    if (this.#groups.size === 0) {\n      return true;\n    }\n    if (!group) {\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.info)(\"Optional content group not defined.\");\n      return true;\n    }\n    if (group.type === \"OCG\") {\n      if (!this.#groups.has(group.id)) {\n        (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(`Optional content group not found: ${group.id}`);\n        return true;\n      }\n      return this.#groups.get(group.id).visible;\n    } else if (group.type === \"OCMD\") {\n      if (group.expression) {\n        return this.#evaluateVisibilityExpression(group.expression);\n      }\n      if (!group.policy || group.policy === \"AnyOn\") {\n        for (const id of group.ids) {\n          if (!this.#groups.has(id)) {\n            (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(`Optional content group not found: ${id}`);\n            return true;\n          }\n          if (this.#groups.get(id).visible) {\n            return true;\n          }\n        }\n        return false;\n      } else if (group.policy === \"AllOn\") {\n        for (const id of group.ids) {\n          if (!this.#groups.has(id)) {\n            (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(`Optional content group not found: ${id}`);\n            return true;\n          }\n          if (!this.#groups.get(id).visible) {\n            return false;\n          }\n        }\n        return true;\n      } else if (group.policy === \"AnyOff\") {\n        for (const id of group.ids) {\n          if (!this.#groups.has(id)) {\n            (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(`Optional content group not found: ${id}`);\n            return true;\n          }\n          if (!this.#groups.get(id).visible) {\n            return true;\n          }\n        }\n        return false;\n      } else if (group.policy === \"AllOff\") {\n        for (const id of group.ids) {\n          if (!this.#groups.has(id)) {\n            (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(`Optional content group not found: ${id}`);\n            return true;\n          }\n          if (this.#groups.get(id).visible) {\n            return false;\n          }\n        }\n        return true;\n      }\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(`Unknown optional content policy ${group.policy}.`);\n      return true;\n    }\n    (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(`Unknown group type ${group.type}.`);\n    return true;\n  }\n  setVisibility(id, visible = true) {\n    const group = this.#groups.get(id);\n    if (!group) {\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(`Optional content group not found: ${id}`);\n      return;\n    }\n    group._setVisible(INTERNAL, !!visible, true);\n    this.#cachedGetHash = null;\n  }\n  setOCGState({\n    state,\n    preserveRB\n  }) {\n    let operator;\n    for (const elem of state) {\n      switch (elem) {\n        case \"ON\":\n        case \"OFF\":\n        case \"Toggle\":\n          operator = elem;\n          continue;\n      }\n      const group = this.#groups.get(elem);\n      if (!group) {\n        continue;\n      }\n      switch (operator) {\n        case \"ON\":\n          group._setVisible(INTERNAL, true);\n          break;\n        case \"OFF\":\n          group._setVisible(INTERNAL, false);\n          break;\n        case \"Toggle\":\n          group._setVisible(INTERNAL, !group.visible);\n          break;\n      }\n    }\n    this.#cachedGetHash = null;\n  }\n  get hasInitialVisibility() {\n    return this.#initialHash === null || this.getHash() === this.#initialHash;\n  }\n  getOrder() {\n    if (!this.#groups.size) {\n      return null;\n    }\n    if (this.#order) {\n      return this.#order.slice();\n    }\n    return [...this.#groups.keys()];\n  }\n  getGroups() {\n    return this.#groups.size > 0 ? (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.objectFromMap)(this.#groups) : null;\n  }\n  getGroup(id) {\n    return this.#groups.get(id) || null;\n  }\n  getHash() {\n    if (this.#cachedGetHash !== null) {\n      return this.#cachedGetHash;\n    }\n    const hash = new _shared_murmurhash3_js__WEBPACK_IMPORTED_MODULE_1__.MurmurHash3_64();\n    for (const [id, group] of this.#groups) {\n      hash.update(`${id}:${group.visible}`);\n    }\n    return this.#cachedGetHash = hash.hexdigest();\n  }\n}\n\n\n/***/ }),\n\n/***/ 651:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   MurmurHash3_64: () => (/* binding */ MurmurHash3_64)\n/* harmony export */ });\nconst SEED = 0xc3d2e1f0;\nconst MASK_HIGH = 0xffff0000;\nconst MASK_LOW = 0xffff;\nclass MurmurHash3_64 {\n  constructor(seed) {\n    this.h1 = seed ? seed & 0xffffffff : SEED;\n    this.h2 = seed ? seed & 0xffffffff : SEED;\n  }\n  update(input) {\n    let data, length;\n    if (typeof input === \"string\") {\n      data = new Uint8Array(input.length * 2);\n      length = 0;\n      for (let i = 0, ii = input.length; i < ii; i++) {\n        const code = input.charCodeAt(i);\n        if (code <= 0xff) {\n          data[length++] = code;\n        } else {\n          data[length++] = code >>> 8;\n          data[length++] = code & 0xff;\n        }\n      }\n    } else if (ArrayBuffer.isView(input)) {\n      data = input.slice();\n      length = data.byteLength;\n    } else {\n      throw new Error(\"Invalid data format, must be a string or TypedArray.\");\n    }\n    const blockCounts = length >> 2;\n    const tailLength = length - blockCounts * 4;\n    const dataUint32 = new Uint32Array(data.buffer, 0, blockCounts);\n    let k1 = 0,\n      k2 = 0;\n    let h1 = this.h1,\n      h2 = this.h2;\n    const C1 = 0xcc9e2d51,\n      C2 = 0x1b873593;\n    const C1_LOW = C1 & MASK_LOW,\n      C2_LOW = C2 & MASK_LOW;\n    for (let i = 0; i < blockCounts; i++) {\n      if (i & 1) {\n        k1 = dataUint32[i];\n        k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW;\n        k1 = k1 << 15 | k1 >>> 17;\n        k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW;\n        h1 ^= k1;\n        h1 = h1 << 13 | h1 >>> 19;\n        h1 = h1 * 5 + 0xe6546b64;\n      } else {\n        k2 = dataUint32[i];\n        k2 = k2 * C1 & MASK_HIGH | k2 * C1_LOW & MASK_LOW;\n        k2 = k2 << 15 | k2 >>> 17;\n        k2 = k2 * C2 & MASK_HIGH | k2 * C2_LOW & MASK_LOW;\n        h2 ^= k2;\n        h2 = h2 << 13 | h2 >>> 19;\n        h2 = h2 * 5 + 0xe6546b64;\n      }\n    }\n    k1 = 0;\n    switch (tailLength) {\n      case 3:\n        k1 ^= data[blockCounts * 4 + 2] << 16;\n      case 2:\n        k1 ^= data[blockCounts * 4 + 1] << 8;\n      case 1:\n        k1 ^= data[blockCounts * 4];\n        k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW;\n        k1 = k1 << 15 | k1 >>> 17;\n        k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW;\n        if (blockCounts & 1) {\n          h1 ^= k1;\n        } else {\n          h2 ^= k1;\n        }\n    }\n    this.h1 = h1;\n    this.h2 = h2;\n  }\n  hexdigest() {\n    let h1 = this.h1,\n      h2 = this.h2;\n    h1 ^= h2 >>> 1;\n    h1 = h1 * 0xed558ccd & MASK_HIGH | h1 * 0x8ccd & MASK_LOW;\n    h2 = h2 * 0xff51afd7 & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xafd7ed55 & MASK_HIGH) >>> 16;\n    h1 ^= h2 >>> 1;\n    h1 = h1 * 0x1a85ec53 & MASK_HIGH | h1 * 0xec53 & MASK_LOW;\n    h2 = h2 * 0xc4ceb9fe & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xb9fe1a85 & MASK_HIGH) >>> 16;\n    h1 ^= h2 >>> 1;\n    return (h1 >>> 0).toString(16).padStart(8, \"0\") + (h2 >>> 0).toString(16).padStart(8, \"0\");\n  }\n}\n\n\n/***/ }),\n\n/***/ 731:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n  AnnotationEditorLayer: () => (/* binding */ AnnotationEditorLayer)\n});\n\n// EXTERNAL MODULE: ./src/shared/util.js\nvar util = __webpack_require__(292);\n// EXTERNAL MODULE: ./src/display/editor/editor.js + 1 modules\nvar editor_editor = __webpack_require__(310);\n// EXTERNAL MODULE: ./src/display/editor/tools.js\nvar tools = __webpack_require__(830);\n// EXTERNAL MODULE: ./src/display/annotation_layer.js + 1 modules\nvar annotation_layer = __webpack_require__(976);\n;// ./src/display/editor/freetext.js\n\n\n\n\nclass FreeTextEditor extends editor_editor.AnnotationEditor {\n  #boundEditorDivBlur = this.editorDivBlur.bind(this);\n  #boundEditorDivFocus = this.editorDivFocus.bind(this);\n  #boundEditorDivInput = this.editorDivInput.bind(this);\n  #boundEditorDivKeydown = this.editorDivKeydown.bind(this);\n  #color;\n  #content = \"\";\n  #editorDivId = `${this.id}-editor`;\n  #fontSize;\n  #initialData = null;\n  static _freeTextDefaultContent = \"\";\n  static _internalPadding = 0;\n  static _defaultColor = null;\n  static _defaultFontSize = 10;\n  static get _keyboardManager() {\n    const proto = FreeTextEditor.prototype;\n    const arrowChecker = self => self.isEmpty();\n    const small = tools.AnnotationEditorUIManager.TRANSLATE_SMALL;\n    const big = tools.AnnotationEditorUIManager.TRANSLATE_BIG;\n    return (0,util.shadow)(this, \"_keyboardManager\", new tools.KeyboardManager([[[\"ctrl+s\", \"mac+meta+s\", \"ctrl+p\", \"mac+meta+p\"], proto.commitOrRemove, {\n      bubbles: true\n    }], [[\"ctrl+Enter\", \"mac+meta+Enter\", \"Escape\", \"mac+Escape\"], proto.commitOrRemove], [[\"ArrowLeft\", \"mac+ArrowLeft\"], proto._translateEmpty, {\n      args: [-small, 0],\n      checker: arrowChecker\n    }], [[\"ctrl+ArrowLeft\", \"mac+shift+ArrowLeft\"], proto._translateEmpty, {\n      args: [-big, 0],\n      checker: arrowChecker\n    }], [[\"ArrowRight\", \"mac+ArrowRight\"], proto._translateEmpty, {\n      args: [small, 0],\n      checker: arrowChecker\n    }], [[\"ctrl+ArrowRight\", \"mac+shift+ArrowRight\"], proto._translateEmpty, {\n      args: [big, 0],\n      checker: arrowChecker\n    }], [[\"ArrowUp\", \"mac+ArrowUp\"], proto._translateEmpty, {\n      args: [0, -small],\n      checker: arrowChecker\n    }], [[\"ctrl+ArrowUp\", \"mac+shift+ArrowUp\"], proto._translateEmpty, {\n      args: [0, -big],\n      checker: arrowChecker\n    }], [[\"ArrowDown\", \"mac+ArrowDown\"], proto._translateEmpty, {\n      args: [0, small],\n      checker: arrowChecker\n    }], [[\"ctrl+ArrowDown\", \"mac+shift+ArrowDown\"], proto._translateEmpty, {\n      args: [0, big],\n      checker: arrowChecker\n    }]]));\n  }\n  static _type = \"freetext\";\n  static _editorType = util.AnnotationEditorType.FREETEXT;\n  constructor(params) {\n    super({\n      ...params,\n      name: \"freeTextEditor\"\n    });\n    this.#color = params.color || FreeTextEditor._defaultColor || editor_editor.AnnotationEditor._defaultLineColor;\n    this.#fontSize = params.fontSize || FreeTextEditor._defaultFontSize;\n  }\n  static initialize(l10n, uiManager) {\n    editor_editor.AnnotationEditor.initialize(l10n, uiManager, {\n      strings: [\"pdfjs-free-text-default-content\"]\n    });\n    const style = getComputedStyle(document.documentElement);\n    this._internalPadding = parseFloat(style.getPropertyValue(\"--freetext-padding\"));\n  }\n  static updateDefaultParams(type, value) {\n    switch (type) {\n      case util.AnnotationEditorParamsType.FREETEXT_SIZE:\n        FreeTextEditor._defaultFontSize = value;\n        break;\n      case util.AnnotationEditorParamsType.FREETEXT_COLOR:\n        FreeTextEditor._defaultColor = value;\n        break;\n    }\n  }\n  updateParams(type, value) {\n    switch (type) {\n      case util.AnnotationEditorParamsType.FREETEXT_SIZE:\n        this.#updateFontSize(value);\n        break;\n      case util.AnnotationEditorParamsType.FREETEXT_COLOR:\n        this.#updateColor(value);\n        break;\n    }\n  }\n  static get defaultPropertiesToUpdate() {\n    return [[util.AnnotationEditorParamsType.FREETEXT_SIZE, FreeTextEditor._defaultFontSize], [util.AnnotationEditorParamsType.FREETEXT_COLOR, FreeTextEditor._defaultColor || editor_editor.AnnotationEditor._defaultLineColor]];\n  }\n  get propertiesToUpdate() {\n    return [[util.AnnotationEditorParamsType.FREETEXT_SIZE, this.#fontSize], [util.AnnotationEditorParamsType.FREETEXT_COLOR, this.#color]];\n  }\n  #updateFontSize(fontSize) {\n    const setFontsize = size => {\n      this.editorDiv.style.fontSize = `calc(${size}px * var(--scale-factor))`;\n      this.translate(0, -(size - this.#fontSize) * this.parentScale);\n      this.#fontSize = size;\n      this.#setEditorDimensions();\n    };\n    const savedFontsize = this.#fontSize;\n    this.addCommands({\n      cmd: setFontsize.bind(this, fontSize),\n      undo: setFontsize.bind(this, savedFontsize),\n      post: this._uiManager.updateUI.bind(this._uiManager, this),\n      mustExec: true,\n      type: util.AnnotationEditorParamsType.FREETEXT_SIZE,\n      overwriteIfSameType: true,\n      keepUndo: true\n    });\n  }\n  #updateColor(color) {\n    const setColor = col => {\n      this.#color = this.editorDiv.style.color = col;\n    };\n    const savedColor = this.#color;\n    this.addCommands({\n      cmd: setColor.bind(this, color),\n      undo: setColor.bind(this, savedColor),\n      post: this._uiManager.updateUI.bind(this._uiManager, this),\n      mustExec: true,\n      type: util.AnnotationEditorParamsType.FREETEXT_COLOR,\n      overwriteIfSameType: true,\n      keepUndo: true\n    });\n  }\n  _translateEmpty(x, y) {\n    this._uiManager.translateSelectedEditors(x, y, true);\n  }\n  getInitialTranslation() {\n    const scale = this.parentScale;\n    return [-FreeTextEditor._internalPadding * scale, -(FreeTextEditor._internalPadding + this.#fontSize) * scale];\n  }\n  rebuild() {\n    if (!this.parent) {\n      return;\n    }\n    super.rebuild();\n    if (this.div === null) {\n      return;\n    }\n    if (!this.isAttachedToDOM) {\n      this.parent.add(this);\n    }\n  }\n  enableEditMode() {\n    if (this.isInEditMode()) {\n      return;\n    }\n    this.parent.setEditingState(false);\n    this.parent.updateToolbar(util.AnnotationEditorType.FREETEXT);\n    super.enableEditMode();\n    this.overlayDiv.classList.remove(\"enabled\");\n    this.editorDiv.contentEditable = true;\n    this._isDraggable = false;\n    this.div.removeAttribute(\"aria-activedescendant\");\n    this.editorDiv.addEventListener(\"keydown\", this.#boundEditorDivKeydown);\n    this.editorDiv.addEventListener(\"focus\", this.#boundEditorDivFocus);\n    this.editorDiv.addEventListener(\"blur\", this.#boundEditorDivBlur);\n    this.editorDiv.addEventListener(\"input\", this.#boundEditorDivInput);\n  }\n  disableEditMode() {\n    if (!this.isInEditMode()) {\n      return;\n    }\n    this.parent.setEditingState(true);\n    super.disableEditMode();\n    this.overlayDiv.classList.add(\"enabled\");\n    this.editorDiv.contentEditable = false;\n    this.div.setAttribute(\"aria-activedescendant\", this.#editorDivId);\n    this._isDraggable = true;\n    this.editorDiv.removeEventListener(\"keydown\", this.#boundEditorDivKeydown);\n    this.editorDiv.removeEventListener(\"focus\", this.#boundEditorDivFocus);\n    this.editorDiv.removeEventListener(\"blur\", this.#boundEditorDivBlur);\n    this.editorDiv.removeEventListener(\"input\", this.#boundEditorDivInput);\n    this.div.focus({\n      preventScroll: true\n    });\n    this.isEditing = false;\n    this.parent.div.classList.add(\"freetextEditing\");\n  }\n  focusin(event) {\n    if (!this._focusEventsAllowed) {\n      return;\n    }\n    super.focusin(event);\n    if (event.target !== this.editorDiv) {\n      this.editorDiv.focus();\n    }\n  }\n  onceAdded() {\n    if (this.width) {\n      this.#cheatInitialRect();\n      return;\n    }\n    this.enableEditMode();\n    this.editorDiv.focus();\n    if (this._initialOptions?.isCentered) {\n      this.center();\n    }\n    this._initialOptions = null;\n  }\n  isEmpty() {\n    return !this.editorDiv || this.editorDiv.innerText.trim() === \"\";\n  }\n  remove() {\n    this.isEditing = false;\n    if (this.parent) {\n      this.parent.setEditingState(true);\n      this.parent.div.classList.add(\"freetextEditing\");\n    }\n    super.remove();\n  }\n  #extractText() {\n    const buffer = [];\n    this.editorDiv.normalize();\n    const EOL_PATTERN = /\\r\\n?|\\n/g;\n    for (const child of this.editorDiv.childNodes) {\n      const content = child.nodeType === Node.TEXT_NODE ? child.nodeValue : child.innerText;\n      buffer.push(content.replaceAll(EOL_PATTERN, \"\"));\n    }\n    return buffer.join(\"\\n\");\n  }\n  #setEditorDimensions() {\n    const [parentWidth, parentHeight] = this.parentDimensions;\n    let rect;\n    if (this.isAttachedToDOM) {\n      rect = this.div.getBoundingClientRect();\n    } else {\n      const {\n        currentLayer,\n        div\n      } = this;\n      const savedDisplay = div.style.display;\n      div.style.display = \"hidden\";\n      currentLayer.div.append(this.div);\n      rect = div.getBoundingClientRect();\n      div.remove();\n      div.style.display = savedDisplay;\n    }\n    if (this.rotation % 180 === this.parentRotation % 180) {\n      this.width = rect.width / parentWidth;\n      this.height = rect.height / parentHeight;\n    } else {\n      this.width = rect.height / parentWidth;\n      this.height = rect.width / parentHeight;\n    }\n    this.fixAndSetPosition();\n  }\n  commit() {\n    if (!this.isInEditMode()) {\n      return;\n    }\n    super.commit();\n    this.disableEditMode();\n    const savedText = this.#content;\n    const newText = this.#content = this.#extractText().trimEnd();\n    if (savedText === newText) {\n      return;\n    }\n    const setText = text => {\n      this.#content = text;\n      if (!text) {\n        this.remove();\n        return;\n      }\n      this.#setContent();\n      this._uiManager.rebuild(this);\n      this.#setEditorDimensions();\n    };\n    this.addCommands({\n      cmd: () => {\n        setText(newText);\n      },\n      undo: () => {\n        setText(savedText);\n      },\n      mustExec: false\n    });\n    this.#setEditorDimensions();\n  }\n  shouldGetKeyboardEvents() {\n    return this.isInEditMode();\n  }\n  enterInEditMode() {\n    this.enableEditMode();\n    this.editorDiv.focus();\n  }\n  dblclick(event) {\n    this.enterInEditMode();\n  }\n  keydown(event) {\n    if (event.target === this.div && event.key === \"Enter\") {\n      this.enterInEditMode();\n      event.preventDefault();\n    }\n  }\n  editorDivKeydown(event) {\n    FreeTextEditor._keyboardManager.exec(this, event);\n  }\n  editorDivFocus(event) {\n    this.isEditing = true;\n  }\n  editorDivBlur(event) {\n    this.isEditing = false;\n  }\n  editorDivInput(event) {\n    this.parent.div.classList.toggle(\"freetextEditing\", this.isEmpty());\n  }\n  disableEditing() {\n    this.editorDiv.setAttribute(\"role\", \"comment\");\n    this.editorDiv.removeAttribute(\"aria-multiline\");\n  }\n  enableEditing() {\n    this.editorDiv.setAttribute(\"role\", \"textbox\");\n    this.editorDiv.setAttribute(\"aria-multiline\", true);\n  }\n  render() {\n    if (this.div) {\n      return this.div;\n    }\n    let baseX, baseY;\n    if (this.width) {\n      baseX = this.x;\n      baseY = this.y;\n    }\n    super.render();\n    this.editorDiv = document.createElement(\"div\");\n    this.editorDiv.className = \"internal\";\n    this.editorDiv.setAttribute(\"id\", this.#editorDivId);\n    this.editorDiv.setAttribute(\"data-l10n-id\", \"pdfjs-free-text\");\n    this.enableEditing();\n    editor_editor.AnnotationEditor._l10nPromise.get(\"pdfjs-free-text-default-content\").then(msg => this.editorDiv?.setAttribute(\"default-content\", msg));\n    this.editorDiv.contentEditable = true;\n    const {\n      style\n    } = this.editorDiv;\n    style.fontSize = `calc(${this.#fontSize}px * var(--scale-factor))`;\n    style.color = this.#color;\n    this.div.append(this.editorDiv);\n    this.overlayDiv = document.createElement(\"div\");\n    this.overlayDiv.classList.add(\"overlay\", \"enabled\");\n    this.div.append(this.overlayDiv);\n    (0,tools.bindEvents)(this, this.div, [\"dblclick\", \"keydown\"]);\n    if (this.width) {\n      const [parentWidth, parentHeight] = this.parentDimensions;\n      if (this.annotationElementId) {\n        const {\n          position\n        } = this.#initialData;\n        let [tx, ty] = this.getInitialTranslation();\n        [tx, ty] = this.pageTranslationToScreen(tx, ty);\n        const [pageWidth, pageHeight] = this.pageDimensions;\n        const [pageX, pageY] = this.pageTranslation;\n        let posX, posY;\n        switch (this.rotation) {\n          case 0:\n            posX = baseX + (position[0] - pageX) / pageWidth;\n            posY = baseY + this.height - (position[1] - pageY) / pageHeight;\n            break;\n          case 90:\n            posX = baseX + (position[0] - pageX) / pageWidth;\n            posY = baseY - (position[1] - pageY) / pageHeight;\n            [tx, ty] = [ty, -tx];\n            break;\n          case 180:\n            posX = baseX - this.width + (position[0] - pageX) / pageWidth;\n            posY = baseY - (position[1] - pageY) / pageHeight;\n            [tx, ty] = [-tx, -ty];\n            break;\n          case 270:\n            posX = baseX + (position[0] - pageX - this.height * pageHeight) / pageWidth;\n            posY = baseY + (position[1] - pageY - this.width * pageWidth) / pageHeight;\n            [tx, ty] = [-ty, tx];\n            break;\n        }\n        this.setAt(posX * parentWidth, posY * parentHeight, tx, ty);\n      } else {\n        this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight);\n      }\n      this.#setContent();\n      this._isDraggable = true;\n      this.editorDiv.contentEditable = false;\n    } else {\n      this._isDraggable = false;\n      this.editorDiv.contentEditable = true;\n    }\n    return this.div;\n  }\n  #setContent() {\n    this.editorDiv.replaceChildren();\n    if (!this.#content) {\n      return;\n    }\n    for (const line of this.#content.split(\"\\n\")) {\n      const div = document.createElement(\"div\");\n      div.append(line ? document.createTextNode(line) : document.createElement(\"br\"));\n      this.editorDiv.append(div);\n    }\n  }\n  #serializeContent() {\n    return this.#content.replaceAll(\"\\xa0\", \" \");\n  }\n  static #deserializeContent(content) {\n    return content.replaceAll(\" \", \"\\xa0\");\n  }\n  get contentDiv() {\n    return this.editorDiv;\n  }\n  static deserialize(data, parent, uiManager) {\n    let initialData = null;\n    if (data instanceof annotation_layer.FreeTextAnnotationElement) {\n      const {\n        data: {\n          defaultAppearanceData: {\n            fontSize,\n            fontColor\n          },\n          rect,\n          rotation,\n          id\n        },\n        textContent,\n        textPosition,\n        parent: {\n          page: {\n            pageNumber\n          }\n        }\n      } = data;\n      if (!textContent || textContent.length === 0) {\n        return null;\n      }\n      initialData = data = {\n        annotationType: util.AnnotationEditorType.FREETEXT,\n        color: Array.from(fontColor),\n        fontSize,\n        value: textContent.join(\"\\n\"),\n        position: textPosition,\n        pageIndex: pageNumber - 1,\n        rect,\n        rotation,\n        id,\n        deleted: false\n      };\n    }\n    const editor = super.deserialize(data, parent, uiManager);\n    editor.#fontSize = data.fontSize;\n    editor.#color = util.Util.makeHexColor(...data.color);\n    editor.#content = FreeTextEditor.#deserializeContent(data.value);\n    editor.annotationElementId = data.id || null;\n    editor.#initialData = initialData;\n    return editor;\n  }\n  serialize(isForCopying = false) {\n    if (this.isEmpty()) {\n      return null;\n    }\n    if (this.deleted) {\n      return {\n        pageIndex: this.pageIndex,\n        id: this.annotationElementId,\n        deleted: true\n      };\n    }\n    const padding = FreeTextEditor._internalPadding * this.parentScale;\n    const rect = this.getRect(padding, padding);\n    const color = editor_editor.AnnotationEditor._colorManager.convert(this.isAttachedToDOM ? getComputedStyle(this.editorDiv).color : this.#color);\n    const serialized = {\n      annotationType: util.AnnotationEditorType.FREETEXT,\n      color,\n      fontSize: this.#fontSize,\n      value: this.#serializeContent(),\n      pageIndex: this.pageIndex,\n      rect,\n      rotation: this.rotation,\n      structTreeParentId: this._structTreeParentId\n    };\n    if (isForCopying) {\n      return serialized;\n    }\n    if (this.annotationElementId && !this.#hasElementChanged(serialized)) {\n      return null;\n    }\n    serialized.id = this.annotationElementId;\n    return serialized;\n  }\n  #hasElementChanged(serialized) {\n    const {\n      value,\n      fontSize,\n      color,\n      rect,\n      pageIndex\n    } = this.#initialData;\n    return serialized.value !== value || serialized.fontSize !== fontSize || serialized.rect.some((x, i) => Math.abs(x - rect[i]) >= 1) || serialized.color.some((c, i) => c !== color[i]) || serialized.pageIndex !== pageIndex;\n  }\n  #cheatInitialRect(delayed = false) {\n    if (!this.annotationElementId) {\n      return;\n    }\n    this.#setEditorDimensions();\n    if (!delayed && (this.width === 0 || this.height === 0)) {\n      setTimeout(() => this.#cheatInitialRect(true), 0);\n      return;\n    }\n    const padding = FreeTextEditor._internalPadding * this.parentScale;\n    this.#initialData.rect = this.getRect(padding, padding);\n  }\n}\n\n// EXTERNAL MODULE: ./src/display/editor/outliner.js\nvar editor_outliner = __webpack_require__(61);\n// EXTERNAL MODULE: ./src/display/editor/color_picker.js\nvar color_picker = __webpack_require__(259);\n// EXTERNAL MODULE: ./src/display/display_utils.js\nvar display_utils = __webpack_require__(419);\n;// ./src/display/editor/highlight.js\n\n\n\n\n\n\nclass HighlightEditor extends editor_editor.AnnotationEditor {\n  #anchorNode = null;\n  #anchorOffset = 0;\n  #boxes;\n  #clipPathId = null;\n  #colorPicker = null;\n  #focusOutlines = null;\n  #focusNode = null;\n  #focusOffset = 0;\n  #highlightDiv = null;\n  #highlightOutlines = null;\n  #id = null;\n  #isFreeHighlight = false;\n  #boundKeydown = this.#keydown.bind(this);\n  #lastPoint = null;\n  #opacity;\n  #outlineId = null;\n  #text = \"\";\n  #thickness;\n  #methodOfCreation = \"\";\n  static _defaultColor = null;\n  static _defaultOpacity = 1;\n  static _defaultThickness = 12;\n  static _l10nPromise;\n  static _type = \"highlight\";\n  static _editorType = util.AnnotationEditorType.HIGHLIGHT;\n  static _freeHighlightId = -1;\n  static _freeHighlight = null;\n  static _freeHighlightClipId = \"\";\n  static get _keyboardManager() {\n    const proto = HighlightEditor.prototype;\n    return (0,util.shadow)(this, \"_keyboardManager\", new tools.KeyboardManager([[[\"ArrowLeft\", \"mac+ArrowLeft\"], proto._moveCaret, {\n      args: [0]\n    }], [[\"ArrowRight\", \"mac+ArrowRight\"], proto._moveCaret, {\n      args: [1]\n    }], [[\"ArrowUp\", \"mac+ArrowUp\"], proto._moveCaret, {\n      args: [2]\n    }], [[\"ArrowDown\", \"mac+ArrowDown\"], proto._moveCaret, {\n      args: [3]\n    }]]));\n  }\n  constructor(params) {\n    super({\n      ...params,\n      name: \"highlightEditor\"\n    });\n    this.color = params.color || HighlightEditor._defaultColor;\n    this.#thickness = params.thickness || HighlightEditor._defaultThickness;\n    this.#opacity = params.opacity || HighlightEditor._defaultOpacity;\n    this.#boxes = params.boxes || null;\n    this.#methodOfCreation = params.methodOfCreation || \"\";\n    this.#text = params.text || \"\";\n    this._isDraggable = false;\n    if (params.highlightId > -1) {\n      this.#isFreeHighlight = true;\n      this.#createFreeOutlines(params);\n      this.#addToDrawLayer();\n    } else {\n      this.#anchorNode = params.anchorNode;\n      this.#anchorOffset = params.anchorOffset;\n      this.#focusNode = params.focusNode;\n      this.#focusOffset = params.focusOffset;\n      this.#createOutlines();\n      this.#addToDrawLayer();\n      this.rotate(this.rotation);\n    }\n  }\n  get telemetryInitialData() {\n    return {\n      action: \"added\",\n      type: this.#isFreeHighlight ? \"free_highlight\" : \"highlight\",\n      color: this._uiManager.highlightColorNames.get(this.color),\n      thickness: this.#thickness,\n      methodOfCreation: this.#methodOfCreation\n    };\n  }\n  get telemetryFinalData() {\n    return {\n      type: \"highlight\",\n      color: this._uiManager.highlightColorNames.get(this.color)\n    };\n  }\n  static computeTelemetryFinalData(data) {\n    return {\n      numberOfColors: data.get(\"color\").size\n    };\n  }\n  #createOutlines() {\n    const outliner = new editor_outliner.Outliner(this.#boxes, 0.001);\n    this.#highlightOutlines = outliner.getOutlines();\n    ({\n      x: this.x,\n      y: this.y,\n      width: this.width,\n      height: this.height\n    } = this.#highlightOutlines.box);\n    const outlinerForOutline = new editor_outliner.Outliner(this.#boxes, 0.0025, 0.001, this._uiManager.direction === \"ltr\");\n    this.#focusOutlines = outlinerForOutline.getOutlines();\n    const {\n      lastPoint\n    } = this.#focusOutlines.box;\n    this.#lastPoint = [(lastPoint[0] - this.x) / this.width, (lastPoint[1] - this.y) / this.height];\n  }\n  #createFreeOutlines({\n    highlightOutlines,\n    highlightId,\n    clipPathId\n  }) {\n    this.#highlightOutlines = highlightOutlines;\n    const extraThickness = 1.5;\n    this.#focusOutlines = highlightOutlines.getNewOutline(this.#thickness / 2 + extraThickness, 0.0025);\n    if (highlightId >= 0) {\n      this.#id = highlightId;\n      this.#clipPathId = clipPathId;\n      this.parent.drawLayer.finalizeLine(highlightId, highlightOutlines);\n      this.#outlineId = this.parent.drawLayer.highlightOutline(this.#focusOutlines);\n    } else if (this.parent) {\n      const angle = this.parent.viewport.rotation;\n      this.parent.drawLayer.updateLine(this.#id, highlightOutlines);\n      this.parent.drawLayer.updateBox(this.#id, HighlightEditor.#rotateBbox(this.#highlightOutlines.box, (angle - this.rotation + 360) % 360));\n      this.parent.drawLayer.updateLine(this.#outlineId, this.#focusOutlines);\n      this.parent.drawLayer.updateBox(this.#outlineId, HighlightEditor.#rotateBbox(this.#focusOutlines.box, angle));\n    }\n    const {\n      x,\n      y,\n      width,\n      height\n    } = highlightOutlines.box;\n    switch (this.rotation) {\n      case 0:\n        this.x = x;\n        this.y = y;\n        this.width = width;\n        this.height = height;\n        break;\n      case 90:\n        {\n          const [pageWidth, pageHeight] = this.parentDimensions;\n          this.x = y;\n          this.y = 1 - x;\n          this.width = width * pageHeight / pageWidth;\n          this.height = height * pageWidth / pageHeight;\n          break;\n        }\n      case 180:\n        this.x = 1 - x;\n        this.y = 1 - y;\n        this.width = width;\n        this.height = height;\n        break;\n      case 270:\n        {\n          const [pageWidth, pageHeight] = this.parentDimensions;\n          this.x = 1 - y;\n          this.y = x;\n          this.width = width * pageHeight / pageWidth;\n          this.height = height * pageWidth / pageHeight;\n          break;\n        }\n    }\n    const {\n      lastPoint\n    } = this.#focusOutlines.box;\n    this.#lastPoint = [(lastPoint[0] - x) / width, (lastPoint[1] - y) / height];\n  }\n  static initialize(l10n, uiManager) {\n    editor_editor.AnnotationEditor.initialize(l10n, uiManager);\n    HighlightEditor._defaultColor ||= uiManager.highlightColors?.values().next().value || \"#fff066\";\n  }\n  static updateDefaultParams(type, value) {\n    switch (type) {\n      case util.AnnotationEditorParamsType.HIGHLIGHT_DEFAULT_COLOR:\n        HighlightEditor._defaultColor = value;\n        break;\n      case util.AnnotationEditorParamsType.HIGHLIGHT_THICKNESS:\n        HighlightEditor._defaultThickness = value;\n        break;\n    }\n  }\n  translateInPage(x, y) {}\n  get toolbarPosition() {\n    return this.#lastPoint;\n  }\n  updateParams(type, value) {\n    switch (type) {\n      case util.AnnotationEditorParamsType.HIGHLIGHT_COLOR:\n        this.#updateColor(value);\n        break;\n      case util.AnnotationEditorParamsType.HIGHLIGHT_THICKNESS:\n        this.#updateThickness(value);\n        break;\n    }\n  }\n  static get defaultPropertiesToUpdate() {\n    return [[util.AnnotationEditorParamsType.HIGHLIGHT_DEFAULT_COLOR, HighlightEditor._defaultColor], [util.AnnotationEditorParamsType.HIGHLIGHT_THICKNESS, HighlightEditor._defaultThickness]];\n  }\n  get propertiesToUpdate() {\n    return [[util.AnnotationEditorParamsType.HIGHLIGHT_COLOR, this.color || HighlightEditor._defaultColor], [util.AnnotationEditorParamsType.HIGHLIGHT_THICKNESS, this.#thickness || HighlightEditor._defaultThickness], [util.AnnotationEditorParamsType.HIGHLIGHT_FREE, this.#isFreeHighlight]];\n  }\n  #updateColor(color) {\n    const setColor = col => {\n      this.color = col;\n      this.parent?.drawLayer.changeColor(this.#id, col);\n      this.#colorPicker?.updateColor(col);\n    };\n    const savedColor = this.color;\n    this.addCommands({\n      cmd: setColor.bind(this, color),\n      undo: setColor.bind(this, savedColor),\n      post: this._uiManager.updateUI.bind(this._uiManager, this),\n      mustExec: true,\n      type: util.AnnotationEditorParamsType.HIGHLIGHT_COLOR,\n      overwriteIfSameType: true,\n      keepUndo: true\n    });\n    this._reportTelemetry({\n      action: \"color_changed\",\n      color: this._uiManager.highlightColorNames.get(color)\n    }, true);\n  }\n  #updateThickness(thickness) {\n    const savedThickness = this.#thickness;\n    const setThickness = th => {\n      this.#thickness = th;\n      this.#changeThickness(th);\n    };\n    this.addCommands({\n      cmd: setThickness.bind(this, thickness),\n      undo: setThickness.bind(this, savedThickness),\n      post: this._uiManager.updateUI.bind(this._uiManager, this),\n      mustExec: true,\n      type: util.AnnotationEditorParamsType.INK_THICKNESS,\n      overwriteIfSameType: true,\n      keepUndo: true\n    });\n    this._reportTelemetry({\n      action: \"thickness_changed\",\n      thickness\n    }, true);\n  }\n  async addEditToolbar() {\n    const toolbar = await super.addEditToolbar();\n    if (!toolbar) {\n      return null;\n    }\n    if (this._uiManager.highlightColors) {\n      this.#colorPicker = new color_picker.ColorPicker({\n        editor: this\n      });\n      toolbar.addColorPicker(this.#colorPicker);\n    }\n    return toolbar;\n  }\n  disableEditing() {\n    super.disableEditing();\n    this.div.classList.toggle(\"disabled\", true);\n  }\n  enableEditing() {\n    super.enableEditing();\n    this.div.classList.toggle(\"disabled\", false);\n  }\n  fixAndSetPosition() {\n    return super.fixAndSetPosition(this.#getRotation());\n  }\n  getBaseTranslation() {\n    return [0, 0];\n  }\n  getRect(tx, ty) {\n    return super.getRect(tx, ty, this.#getRotation());\n  }\n  onceAdded() {\n    this.parent.addUndoableEditor(this);\n    this.div.focus();\n  }\n  remove() {\n    super.remove();\n    this.#cleanDrawLayer();\n    this._reportTelemetry({\n      action: \"deleted\"\n    });\n  }\n  rebuild() {\n    if (!this.parent) {\n      return;\n    }\n    super.rebuild();\n    if (this.div === null) {\n      return;\n    }\n    this.#addToDrawLayer();\n    if (!this.isAttachedToDOM) {\n      this.parent.add(this);\n    }\n  }\n  setParent(parent) {\n    let mustBeSelected = false;\n    if (this.parent && !parent) {\n      this.#cleanDrawLayer();\n    } else if (parent) {\n      this.#addToDrawLayer(parent);\n      mustBeSelected = !this.parent && this.div?.classList.contains(\"selectedEditor\");\n    }\n    super.setParent(parent);\n    this.show(this._isVisible);\n    if (mustBeSelected) {\n      this.select();\n    }\n  }\n  #changeThickness(thickness) {\n    if (!this.#isFreeHighlight) {\n      return;\n    }\n    this.#createFreeOutlines({\n      highlightOutlines: this.#highlightOutlines.getNewOutline(thickness / 2)\n    });\n    this.fixAndSetPosition();\n    const [parentWidth, parentHeight] = this.parentDimensions;\n    this.setDims(this.width * parentWidth, this.height * parentHeight);\n  }\n  #cleanDrawLayer() {\n    if (this.#id === null || !this.parent) {\n      return;\n    }\n    this.parent.drawLayer.remove(this.#id);\n    this.#id = null;\n    this.parent.drawLayer.remove(this.#outlineId);\n    this.#outlineId = null;\n  }\n  #addToDrawLayer(parent = this.parent) {\n    if (this.#id !== null) {\n      return;\n    }\n    ({\n      id: this.#id,\n      clipPathId: this.#clipPathId\n    } = parent.drawLayer.highlight(this.#highlightOutlines, this.color, this.#opacity));\n    this.#outlineId = parent.drawLayer.highlightOutline(this.#focusOutlines);\n    if (this.#highlightDiv) {\n      this.#highlightDiv.style.clipPath = this.#clipPathId;\n    }\n  }\n  static #rotateBbox({\n    x,\n    y,\n    width,\n    height\n  }, angle) {\n    switch (angle) {\n      case 90:\n        return {\n          x: 1 - y - height,\n          y: x,\n          width: height,\n          height: width\n        };\n      case 180:\n        return {\n          x: 1 - x - width,\n          y: 1 - y - height,\n          width,\n          height\n        };\n      case 270:\n        return {\n          x: y,\n          y: 1 - x - width,\n          width: height,\n          height: width\n        };\n    }\n    return {\n      x,\n      y,\n      width,\n      height\n    };\n  }\n  rotate(angle) {\n    const {\n      drawLayer\n    } = this.parent;\n    let box;\n    if (this.#isFreeHighlight) {\n      angle = (angle - this.rotation + 360) % 360;\n      box = HighlightEditor.#rotateBbox(this.#highlightOutlines.box, angle);\n    } else {\n      box = HighlightEditor.#rotateBbox(this, angle);\n    }\n    drawLayer.rotate(this.#id, angle);\n    drawLayer.rotate(this.#outlineId, angle);\n    drawLayer.updateBox(this.#id, box);\n    drawLayer.updateBox(this.#outlineId, HighlightEditor.#rotateBbox(this.#focusOutlines.box, angle));\n  }\n  render() {\n    if (this.div) {\n      return this.div;\n    }\n    const div = super.render();\n    if (this.#text) {\n      const mark = document.createElement(\"mark\");\n      div.append(mark);\n      mark.append(document.createTextNode(this.#text));\n      mark.className = \"visuallyHidden\";\n    }\n    if (this.#isFreeHighlight) {\n      div.classList.add(\"free\");\n    } else {\n      this.div.addEventListener(\"keydown\", this.#boundKeydown);\n    }\n    const highlightDiv = this.#highlightDiv = document.createElement(\"div\");\n    div.append(highlightDiv);\n    highlightDiv.setAttribute(\"aria-hidden\", \"true\");\n    highlightDiv.className = \"internal\";\n    highlightDiv.style.clipPath = this.#clipPathId;\n    const [parentWidth, parentHeight] = this.parentDimensions;\n    this.setDims(this.width * parentWidth, this.height * parentHeight);\n    (0,tools.bindEvents)(this, this.#highlightDiv, [\"pointerover\", \"pointerleave\"]);\n    this.enableEditing();\n    return div;\n  }\n  pointerover() {\n    this.parent.drawLayer.addClass(this.#outlineId, \"hovered\");\n  }\n  pointerleave() {\n    this.parent.drawLayer.removeClass(this.#outlineId, \"hovered\");\n  }\n  #keydown(event) {\n    HighlightEditor._keyboardManager.exec(this, event);\n  }\n  _moveCaret(direction) {\n    this.parent.unselect(this);\n    switch (direction) {\n      case 0:\n      case 2:\n        this.#setCaret(true);\n        break;\n      case 1:\n      case 3:\n        this.#setCaret(false);\n        break;\n    }\n  }\n  #setCaret(start) {\n    if (!this.#anchorNode) {\n      return;\n    }\n    const selection = window.getSelection();\n    if (start) {\n      selection.setPosition(this.#anchorNode, this.#anchorOffset);\n    } else {\n      selection.setPosition(this.#focusNode, this.#focusOffset);\n    }\n  }\n  select() {\n    super.select();\n    this.parent?.drawLayer.removeClass(this.#outlineId, \"hovered\");\n    this.parent?.drawLayer.addClass(this.#outlineId, \"selected\");\n  }\n  unselect() {\n    super.unselect();\n    this.parent?.drawLayer.removeClass(this.#outlineId, \"selected\");\n    if (!this.#isFreeHighlight) {\n      this.#setCaret(false);\n    }\n  }\n  get _mustFixPosition() {\n    return !this.#isFreeHighlight;\n  }\n  show(visible) {\n    super.show(visible);\n    if (this.parent) {\n      this.parent.drawLayer.show(this.#id, visible);\n      this.parent.drawLayer.show(this.#outlineId, visible);\n    }\n  }\n  #getRotation() {\n    return this.#isFreeHighlight ? this.rotation : 0;\n  }\n  #serializeBoxes() {\n    if (this.#isFreeHighlight) {\n      return null;\n    }\n    const [pageWidth, pageHeight] = this.pageDimensions;\n    const boxes = this.#boxes;\n    const quadPoints = new Array(boxes.length * 8);\n    let i = 0;\n    for (const {\n      x,\n      y,\n      width,\n      height\n    } of boxes) {\n      const sx = x * pageWidth;\n      const sy = (1 - y - height) * pageHeight;\n      quadPoints[i] = quadPoints[i + 4] = sx;\n      quadPoints[i + 1] = quadPoints[i + 3] = sy;\n      quadPoints[i + 2] = quadPoints[i + 6] = sx + width * pageWidth;\n      quadPoints[i + 5] = quadPoints[i + 7] = sy + height * pageHeight;\n      i += 8;\n    }\n    return quadPoints;\n  }\n  #serializeOutlines(rect) {\n    return this.#highlightOutlines.serialize(rect, this.#getRotation());\n  }\n  static startHighlighting(parent, isLTR, {\n    target: textLayer,\n    x,\n    y\n  }) {\n    const {\n      x: layerX,\n      y: layerY,\n      width: parentWidth,\n      height: parentHeight\n    } = textLayer.getBoundingClientRect();\n    const pointerMove = e => {\n      this.#highlightMove(parent, e);\n    };\n    const pointerDownOptions = {\n      capture: true,\n      passive: false\n    };\n    const pointerDown = e => {\n      e.preventDefault();\n      e.stopPropagation();\n    };\n    const pointerUpCallback = e => {\n      textLayer.removeEventListener(\"pointermove\", pointerMove);\n      window.removeEventListener(\"blur\", pointerUpCallback);\n      window.removeEventListener(\"pointerup\", pointerUpCallback);\n      window.removeEventListener(\"pointerdown\", pointerDown, pointerDownOptions);\n      window.removeEventListener(\"contextmenu\", display_utils.noContextMenu);\n      this.#endHighlight(parent, e);\n    };\n    window.addEventListener(\"blur\", pointerUpCallback);\n    window.addEventListener(\"pointerup\", pointerUpCallback);\n    window.addEventListener(\"pointerdown\", pointerDown, pointerDownOptions);\n    window.addEventListener(\"contextmenu\", display_utils.noContextMenu);\n    textLayer.addEventListener(\"pointermove\", pointerMove);\n    this._freeHighlight = new editor_outliner.FreeOutliner({\n      x,\n      y\n    }, [layerX, layerY, parentWidth, parentHeight], parent.scale, this._defaultThickness / 2, isLTR, 0.001);\n    ({\n      id: this._freeHighlightId,\n      clipPathId: this._freeHighlightClipId\n    } = parent.drawLayer.highlight(this._freeHighlight, this._defaultColor, this._defaultOpacity, true));\n  }\n  static #highlightMove(parent, event) {\n    if (this._freeHighlight.add(event)) {\n      parent.drawLayer.updatePath(this._freeHighlightId, this._freeHighlight);\n    }\n  }\n  static #endHighlight(parent, event) {\n    if (!this._freeHighlight.isEmpty()) {\n      parent.createAndAddNewEditor(event, false, {\n        highlightId: this._freeHighlightId,\n        highlightOutlines: this._freeHighlight.getOutlines(),\n        clipPathId: this._freeHighlightClipId,\n        methodOfCreation: \"main_toolbar\"\n      });\n    } else {\n      parent.drawLayer.removeFreeHighlight(this._freeHighlightId);\n    }\n    this._freeHighlightId = -1;\n    this._freeHighlight = null;\n    this._freeHighlightClipId = \"\";\n  }\n  static deserialize(data, parent, uiManager) {\n    const editor = super.deserialize(data, parent, uiManager);\n    const {\n      rect: [blX, blY, trX, trY],\n      color,\n      quadPoints\n    } = data;\n    editor.color = util.Util.makeHexColor(...color);\n    editor.#opacity = data.opacity;\n    const [pageWidth, pageHeight] = editor.pageDimensions;\n    editor.width = (trX - blX) / pageWidth;\n    editor.height = (trY - blY) / pageHeight;\n    const boxes = editor.#boxes = [];\n    for (let i = 0; i < quadPoints.length; i += 8) {\n      boxes.push({\n        x: (quadPoints[4] - trX) / pageWidth,\n        y: (trY - (1 - quadPoints[i + 5])) / pageHeight,\n        width: (quadPoints[i + 2] - quadPoints[i]) / pageWidth,\n        height: (quadPoints[i + 5] - quadPoints[i + 1]) / pageHeight\n      });\n    }\n    editor.#createOutlines();\n    return editor;\n  }\n  serialize(isForCopying = false) {\n    if (this.isEmpty() || isForCopying) {\n      return null;\n    }\n    const rect = this.getRect(0, 0);\n    const color = editor_editor.AnnotationEditor._colorManager.convert(this.color);\n    return {\n      annotationType: util.AnnotationEditorType.HIGHLIGHT,\n      color,\n      opacity: this.#opacity,\n      thickness: this.#thickness,\n      quadPoints: this.#serializeBoxes(),\n      outlines: this.#serializeOutlines(rect),\n      pageIndex: this.pageIndex,\n      rect,\n      rotation: this.#getRotation(),\n      structTreeParentId: this._structTreeParentId\n    };\n  }\n  static canCreateNewEmptyEditor() {\n    return false;\n  }\n}\n\n;// ./src/display/editor/ink.js\n\n\n\n\n\nclass InkEditor extends editor_editor.AnnotationEditor {\n  #baseHeight = 0;\n  #baseWidth = 0;\n  #boundCanvasPointermove = this.canvasPointermove.bind(this);\n  #boundCanvasPointerleave = this.canvasPointerleave.bind(this);\n  #boundCanvasPointerup = this.canvasPointerup.bind(this);\n  #boundCanvasPointerdown = this.canvasPointerdown.bind(this);\n  #canvasContextMenuTimeoutId = null;\n  #currentPath2D = new Path2D();\n  #disableEditing = false;\n  #hasSomethingToDraw = false;\n  #isCanvasInitialized = false;\n  #observer = null;\n  #realWidth = 0;\n  #realHeight = 0;\n  #requestFrameCallback = null;\n  static _defaultColor = null;\n  static _defaultOpacity = 1;\n  static _defaultThickness = 1;\n  static _type = \"ink\";\n  static _editorType = util.AnnotationEditorType.INK;\n  constructor(params) {\n    super({\n      ...params,\n      name: \"inkEditor\"\n    });\n    this.color = params.color || null;\n    this.thickness = params.thickness || null;\n    this.opacity = params.opacity || null;\n    this.paths = [];\n    this.bezierPath2D = [];\n    this.allRawPaths = [];\n    this.currentPath = [];\n    this.scaleFactor = 1;\n    this.translationX = this.translationY = 0;\n    this.x = 0;\n    this.y = 0;\n    this._willKeepAspectRatio = true;\n  }\n  static initialize(l10n, uiManager) {\n    editor_editor.AnnotationEditor.initialize(l10n, uiManager);\n  }\n  static updateDefaultParams(type, value) {\n    switch (type) {\n      case util.AnnotationEditorParamsType.INK_THICKNESS:\n        InkEditor._defaultThickness = value;\n        break;\n      case util.AnnotationEditorParamsType.INK_COLOR:\n        InkEditor._defaultColor = value;\n        break;\n      case util.AnnotationEditorParamsType.INK_OPACITY:\n        InkEditor._defaultOpacity = value / 100;\n        break;\n    }\n  }\n  updateParams(type, value) {\n    switch (type) {\n      case util.AnnotationEditorParamsType.INK_THICKNESS:\n        this.#updateThickness(value);\n        break;\n      case util.AnnotationEditorParamsType.INK_COLOR:\n        this.#updateColor(value);\n        break;\n      case util.AnnotationEditorParamsType.INK_OPACITY:\n        this.#updateOpacity(value);\n        break;\n    }\n  }\n  static get defaultPropertiesToUpdate() {\n    return [[util.AnnotationEditorParamsType.INK_THICKNESS, InkEditor._defaultThickness], [util.AnnotationEditorParamsType.INK_COLOR, InkEditor._defaultColor || editor_editor.AnnotationEditor._defaultLineColor], [util.AnnotationEditorParamsType.INK_OPACITY, Math.round(InkEditor._defaultOpacity * 100)]];\n  }\n  get propertiesToUpdate() {\n    return [[util.AnnotationEditorParamsType.INK_THICKNESS, this.thickness || InkEditor._defaultThickness], [util.AnnotationEditorParamsType.INK_COLOR, this.color || InkEditor._defaultColor || editor_editor.AnnotationEditor._defaultLineColor], [util.AnnotationEditorParamsType.INK_OPACITY, Math.round(100 * (this.opacity ?? InkEditor._defaultOpacity))]];\n  }\n  #updateThickness(thickness) {\n    const setThickness = th => {\n      this.thickness = th;\n      this.#fitToContent();\n    };\n    const savedThickness = this.thickness;\n    this.addCommands({\n      cmd: setThickness.bind(this, thickness),\n      undo: setThickness.bind(this, savedThickness),\n      post: this._uiManager.updateUI.bind(this._uiManager, this),\n      mustExec: true,\n      type: util.AnnotationEditorParamsType.INK_THICKNESS,\n      overwriteIfSameType: true,\n      keepUndo: true\n    });\n  }\n  #updateColor(color) {\n    const setColor = col => {\n      this.color = col;\n      this.#redraw();\n    };\n    const savedColor = this.color;\n    this.addCommands({\n      cmd: setColor.bind(this, color),\n      undo: setColor.bind(this, savedColor),\n      post: this._uiManager.updateUI.bind(this._uiManager, this),\n      mustExec: true,\n      type: util.AnnotationEditorParamsType.INK_COLOR,\n      overwriteIfSameType: true,\n      keepUndo: true\n    });\n  }\n  #updateOpacity(opacity) {\n    const setOpacity = op => {\n      this.opacity = op;\n      this.#redraw();\n    };\n    opacity /= 100;\n    const savedOpacity = this.opacity;\n    this.addCommands({\n      cmd: setOpacity.bind(this, opacity),\n      undo: setOpacity.bind(this, savedOpacity),\n      post: this._uiManager.updateUI.bind(this._uiManager, this),\n      mustExec: true,\n      type: util.AnnotationEditorParamsType.INK_OPACITY,\n      overwriteIfSameType: true,\n      keepUndo: true\n    });\n  }\n  rebuild() {\n    if (!this.parent) {\n      return;\n    }\n    super.rebuild();\n    if (this.div === null) {\n      return;\n    }\n    if (!this.canvas) {\n      this.#createCanvas();\n      this.#createObserver();\n    }\n    if (!this.isAttachedToDOM) {\n      this.parent.add(this);\n      this.#setCanvasDims();\n    }\n    this.#fitToContent();\n  }\n  remove() {\n    if (this.canvas === null) {\n      return;\n    }\n    if (!this.isEmpty()) {\n      this.commit();\n    }\n    this.canvas.width = this.canvas.height = 0;\n    this.canvas.remove();\n    this.canvas = null;\n    if (this.#canvasContextMenuTimeoutId) {\n      clearTimeout(this.#canvasContextMenuTimeoutId);\n      this.#canvasContextMenuTimeoutId = null;\n    }\n    this.#observer.disconnect();\n    this.#observer = null;\n    super.remove();\n  }\n  setParent(parent) {\n    if (!this.parent && parent) {\n      this._uiManager.removeShouldRescale(this);\n    } else if (this.parent && parent === null) {\n      this._uiManager.addShouldRescale(this);\n    }\n    super.setParent(parent);\n  }\n  onScaleChanging() {\n    const [parentWidth, parentHeight] = this.parentDimensions;\n    const width = this.width * parentWidth;\n    const height = this.height * parentHeight;\n    this.setDimensions(width, height);\n  }\n  enableEditMode() {\n    if (this.#disableEditing || this.canvas === null) {\n      return;\n    }\n    super.enableEditMode();\n    this._isDraggable = false;\n    this.canvas.addEventListener(\"pointerdown\", this.#boundCanvasPointerdown);\n  }\n  disableEditMode() {\n    if (!this.isInEditMode() || this.canvas === null) {\n      return;\n    }\n    super.disableEditMode();\n    this._isDraggable = !this.isEmpty();\n    this.div.classList.remove(\"editing\");\n    this.canvas.removeEventListener(\"pointerdown\", this.#boundCanvasPointerdown);\n  }\n  onceAdded() {\n    this._isDraggable = !this.isEmpty();\n  }\n  isEmpty() {\n    return this.paths.length === 0 || this.paths.length === 1 && this.paths[0].length === 0;\n  }\n  #getInitialBBox() {\n    const {\n      parentRotation,\n      parentDimensions: [width, height]\n    } = this;\n    switch (parentRotation) {\n      case 90:\n        return [0, height, height, width];\n      case 180:\n        return [width, height, width, height];\n      case 270:\n        return [width, 0, height, width];\n      default:\n        return [0, 0, width, height];\n    }\n  }\n  #setStroke() {\n    const {\n      ctx,\n      color,\n      opacity,\n      thickness,\n      parentScale,\n      scaleFactor\n    } = this;\n    ctx.lineWidth = thickness * parentScale / scaleFactor;\n    ctx.lineCap = \"round\";\n    ctx.lineJoin = \"round\";\n    ctx.miterLimit = 10;\n    ctx.strokeStyle = `${color}${(0,tools.opacityToHex)(opacity)}`;\n  }\n  #startDrawing(x, y) {\n    this.canvas.addEventListener(\"contextmenu\", display_utils.noContextMenu);\n    this.canvas.addEventListener(\"pointerleave\", this.#boundCanvasPointerleave);\n    this.canvas.addEventListener(\"pointermove\", this.#boundCanvasPointermove);\n    this.canvas.addEventListener(\"pointerup\", this.#boundCanvasPointerup);\n    this.canvas.removeEventListener(\"pointerdown\", this.#boundCanvasPointerdown);\n    this.isEditing = true;\n    if (!this.#isCanvasInitialized) {\n      this.#isCanvasInitialized = true;\n      this.#setCanvasDims();\n      this.thickness ||= InkEditor._defaultThickness;\n      this.color ||= InkEditor._defaultColor || editor_editor.AnnotationEditor._defaultLineColor;\n      this.opacity ??= InkEditor._defaultOpacity;\n    }\n    this.currentPath.push([x, y]);\n    this.#hasSomethingToDraw = false;\n    this.#setStroke();\n    this.#requestFrameCallback = () => {\n      this.#drawPoints();\n      if (this.#requestFrameCallback) {\n        window.requestAnimationFrame(this.#requestFrameCallback);\n      }\n    };\n    window.requestAnimationFrame(this.#requestFrameCallback);\n  }\n  #draw(x, y) {\n    const [lastX, lastY] = this.currentPath.at(-1);\n    if (this.currentPath.length > 1 && x === lastX && y === lastY) {\n      return;\n    }\n    const currentPath = this.currentPath;\n    let path2D = this.#currentPath2D;\n    currentPath.push([x, y]);\n    this.#hasSomethingToDraw = true;\n    if (currentPath.length <= 2) {\n      path2D.moveTo(...currentPath[0]);\n      path2D.lineTo(x, y);\n      return;\n    }\n    if (currentPath.length === 3) {\n      this.#currentPath2D = path2D = new Path2D();\n      path2D.moveTo(...currentPath[0]);\n    }\n    this.#makeBezierCurve(path2D, ...currentPath.at(-3), ...currentPath.at(-2), x, y);\n  }\n  #endPath() {\n    if (this.currentPath.length === 0) {\n      return;\n    }\n    const lastPoint = this.currentPath.at(-1);\n    this.#currentPath2D.lineTo(...lastPoint);\n  }\n  #stopDrawing(x, y) {\n    this.#requestFrameCallback = null;\n    x = Math.min(Math.max(x, 0), this.canvas.width);\n    y = Math.min(Math.max(y, 0), this.canvas.height);\n    this.#draw(x, y);\n    this.#endPath();\n    let bezier;\n    if (this.currentPath.length !== 1) {\n      bezier = this.#generateBezierPoints();\n    } else {\n      const xy = [x, y];\n      bezier = [[xy, xy.slice(), xy.slice(), xy]];\n    }\n    const path2D = this.#currentPath2D;\n    const currentPath = this.currentPath;\n    this.currentPath = [];\n    this.#currentPath2D = new Path2D();\n    const cmd = () => {\n      this.allRawPaths.push(currentPath);\n      this.paths.push(bezier);\n      this.bezierPath2D.push(path2D);\n      this.rebuild();\n    };\n    const undo = () => {\n      this.allRawPaths.pop();\n      this.paths.pop();\n      this.bezierPath2D.pop();\n      if (this.paths.length === 0) {\n        this.remove();\n      } else {\n        if (!this.canvas) {\n          this.#createCanvas();\n          this.#createObserver();\n        }\n        this.#fitToContent();\n      }\n    };\n    this.addCommands({\n      cmd,\n      undo,\n      mustExec: true\n    });\n  }\n  #drawPoints() {\n    if (!this.#hasSomethingToDraw) {\n      return;\n    }\n    this.#hasSomethingToDraw = false;\n    const thickness = Math.ceil(this.thickness * this.parentScale);\n    const lastPoints = this.currentPath.slice(-3);\n    const x = lastPoints.map(xy => xy[0]);\n    const y = lastPoints.map(xy => xy[1]);\n    const xMin = Math.min(...x) - thickness;\n    const xMax = Math.max(...x) + thickness;\n    const yMin = Math.min(...y) - thickness;\n    const yMax = Math.max(...y) + thickness;\n    const {\n      ctx\n    } = this;\n    ctx.save();\n    ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n    for (const path of this.bezierPath2D) {\n      ctx.stroke(path);\n    }\n    ctx.stroke(this.#currentPath2D);\n    ctx.restore();\n  }\n  #makeBezierCurve(path2D, x0, y0, x1, y1, x2, y2) {\n    const prevX = (x0 + x1) / 2;\n    const prevY = (y0 + y1) / 2;\n    const x3 = (x1 + x2) / 2;\n    const y3 = (y1 + y2) / 2;\n    path2D.bezierCurveTo(prevX + 2 * (x1 - prevX) / 3, prevY + 2 * (y1 - prevY) / 3, x3 + 2 * (x1 - x3) / 3, y3 + 2 * (y1 - y3) / 3, x3, y3);\n  }\n  #generateBezierPoints() {\n    const path = this.currentPath;\n    if (path.length <= 2) {\n      return [[path[0], path[0], path.at(-1), path.at(-1)]];\n    }\n    const bezierPoints = [];\n    let i;\n    let [x0, y0] = path[0];\n    for (i = 1; i < path.length - 2; i++) {\n      const [x1, y1] = path[i];\n      const [x2, y2] = path[i + 1];\n      const x3 = (x1 + x2) / 2;\n      const y3 = (y1 + y2) / 2;\n      const control1 = [x0 + 2 * (x1 - x0) / 3, y0 + 2 * (y1 - y0) / 3];\n      const control2 = [x3 + 2 * (x1 - x3) / 3, y3 + 2 * (y1 - y3) / 3];\n      bezierPoints.push([[x0, y0], control1, control2, [x3, y3]]);\n      [x0, y0] = [x3, y3];\n    }\n    const [x1, y1] = path[i];\n    const [x2, y2] = path[i + 1];\n    const control1 = [x0 + 2 * (x1 - x0) / 3, y0 + 2 * (y1 - y0) / 3];\n    const control2 = [x2 + 2 * (x1 - x2) / 3, y2 + 2 * (y1 - y2) / 3];\n    bezierPoints.push([[x0, y0], control1, control2, [x2, y2]]);\n    return bezierPoints;\n  }\n  #redraw() {\n    if (this.isEmpty()) {\n      this.#updateTransform();\n      return;\n    }\n    this.#setStroke();\n    const {\n      canvas,\n      ctx\n    } = this;\n    ctx.setTransform(1, 0, 0, 1, 0, 0);\n    ctx.clearRect(0, 0, canvas.width, canvas.height);\n    this.#updateTransform();\n    for (const path of this.bezierPath2D) {\n      ctx.stroke(path);\n    }\n  }\n  commit() {\n    if (this.#disableEditing) {\n      return;\n    }\n    super.commit();\n    this.isEditing = false;\n    this.disableEditMode();\n    this.setInForeground();\n    this.#disableEditing = true;\n    this.div.classList.add(\"disabled\");\n    this.#fitToContent(true);\n    this.select();\n    this.parent.addInkEditorIfNeeded(true);\n    this.moveInDOM();\n    this.div.focus({\n      preventScroll: true\n    });\n  }\n  focusin(event) {\n    if (!this._focusEventsAllowed) {\n      return;\n    }\n    super.focusin(event);\n    this.enableEditMode();\n  }\n  canvasPointerdown(event) {\n    if (event.button !== 0 || !this.isInEditMode() || this.#disableEditing) {\n      return;\n    }\n    this.setInForeground();\n    event.preventDefault();\n    if (!this.div.contains(document.activeElement)) {\n      this.div.focus({\n        preventScroll: true\n      });\n    }\n    this.#startDrawing(event.offsetX, event.offsetY);\n  }\n  canvasPointermove(event) {\n    event.preventDefault();\n    this.#draw(event.offsetX, event.offsetY);\n  }\n  canvasPointerup(event) {\n    event.preventDefault();\n    this.#endDrawing(event);\n  }\n  canvasPointerleave(event) {\n    this.#endDrawing(event);\n  }\n  #endDrawing(event) {\n    this.canvas.removeEventListener(\"pointerleave\", this.#boundCanvasPointerleave);\n    this.canvas.removeEventListener(\"pointermove\", this.#boundCanvasPointermove);\n    this.canvas.removeEventListener(\"pointerup\", this.#boundCanvasPointerup);\n    this.canvas.addEventListener(\"pointerdown\", this.#boundCanvasPointerdown);\n    if (this.#canvasContextMenuTimeoutId) {\n      clearTimeout(this.#canvasContextMenuTimeoutId);\n    }\n    this.#canvasContextMenuTimeoutId = setTimeout(() => {\n      this.#canvasContextMenuTimeoutId = null;\n      this.canvas.removeEventListener(\"contextmenu\", display_utils.noContextMenu);\n    }, 10);\n    this.#stopDrawing(event.offsetX, event.offsetY);\n    this.addToAnnotationStorage();\n    this.setInBackground();\n  }\n  #createCanvas() {\n    this.canvas = document.createElement(\"canvas\");\n    this.canvas.width = this.canvas.height = 0;\n    this.canvas.className = \"inkEditorCanvas\";\n    this.canvas.setAttribute(\"data-l10n-id\", \"pdfjs-ink-canvas\");\n    this.div.append(this.canvas);\n    this.ctx = this.canvas.getContext(\"2d\");\n  }\n  #createObserver() {\n    this.#observer = new ResizeObserver(entries => {\n      const rect = entries[0].contentRect;\n      if (rect.width && rect.height) {\n        this.setDimensions(rect.width, rect.height);\n      }\n    });\n    this.#observer.observe(this.div);\n  }\n  get isResizable() {\n    return !this.isEmpty() && this.#disableEditing;\n  }\n  render() {\n    if (this.div) {\n      return this.div;\n    }\n    let baseX, baseY;\n    if (this.width) {\n      baseX = this.x;\n      baseY = this.y;\n    }\n    super.render();\n    this.div.setAttribute(\"data-l10n-id\", \"pdfjs-ink\");\n    const [x, y, w, h] = this.#getInitialBBox();\n    this.setAt(x, y, 0, 0);\n    this.setDims(w, h);\n    this.#createCanvas();\n    if (this.width) {\n      const [parentWidth, parentHeight] = this.parentDimensions;\n      this.setAspectRatio(this.width * parentWidth, this.height * parentHeight);\n      this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight);\n      this.#isCanvasInitialized = true;\n      this.#setCanvasDims();\n      this.setDims(this.width * parentWidth, this.height * parentHeight);\n      this.#redraw();\n      this.div.classList.add(\"disabled\");\n    } else {\n      this.div.classList.add(\"editing\");\n      this.enableEditMode();\n    }\n    this.#createObserver();\n    return this.div;\n  }\n  #setCanvasDims() {\n    if (!this.#isCanvasInitialized) {\n      return;\n    }\n    const [parentWidth, parentHeight] = this.parentDimensions;\n    this.canvas.width = Math.ceil(this.width * parentWidth);\n    this.canvas.height = Math.ceil(this.height * parentHeight);\n    this.#updateTransform();\n  }\n  setDimensions(width, height) {\n    const roundedWidth = Math.round(width);\n    const roundedHeight = Math.round(height);\n    if (this.#realWidth === roundedWidth && this.#realHeight === roundedHeight) {\n      return;\n    }\n    this.#realWidth = roundedWidth;\n    this.#realHeight = roundedHeight;\n    this.canvas.style.visibility = \"hidden\";\n    const [parentWidth, parentHeight] = this.parentDimensions;\n    this.width = width / parentWidth;\n    this.height = height / parentHeight;\n    this.fixAndSetPosition();\n    if (this.#disableEditing) {\n      this.#setScaleFactor(width, height);\n    }\n    this.#setCanvasDims();\n    this.#redraw();\n    this.canvas.style.visibility = \"visible\";\n    this.fixDims();\n  }\n  #setScaleFactor(width, height) {\n    const padding = this.#getPadding();\n    const scaleFactorW = (width - padding) / this.#baseWidth;\n    const scaleFactorH = (height - padding) / this.#baseHeight;\n    this.scaleFactor = Math.min(scaleFactorW, scaleFactorH);\n  }\n  #updateTransform() {\n    const padding = this.#getPadding() / 2;\n    this.ctx.setTransform(this.scaleFactor, 0, 0, this.scaleFactor, this.translationX * this.scaleFactor + padding, this.translationY * this.scaleFactor + padding);\n  }\n  static #buildPath2D(bezier) {\n    const path2D = new Path2D();\n    for (let i = 0, ii = bezier.length; i < ii; i++) {\n      const [first, control1, control2, second] = bezier[i];\n      if (i === 0) {\n        path2D.moveTo(...first);\n      }\n      path2D.bezierCurveTo(control1[0], control1[1], control2[0], control2[1], second[0], second[1]);\n    }\n    return path2D;\n  }\n  static #toPDFCoordinates(points, rect, rotation) {\n    const [blX, blY, trX, trY] = rect;\n    switch (rotation) {\n      case 0:\n        for (let i = 0, ii = points.length; i < ii; i += 2) {\n          points[i] += blX;\n          points[i + 1] = trY - points[i + 1];\n        }\n        break;\n      case 90:\n        for (let i = 0, ii = points.length; i < ii; i += 2) {\n          const x = points[i];\n          points[i] = points[i + 1] + blX;\n          points[i + 1] = x + blY;\n        }\n        break;\n      case 180:\n        for (let i = 0, ii = points.length; i < ii; i += 2) {\n          points[i] = trX - points[i];\n          points[i + 1] += blY;\n        }\n        break;\n      case 270:\n        for (let i = 0, ii = points.length; i < ii; i += 2) {\n          const x = points[i];\n          points[i] = trX - points[i + 1];\n          points[i + 1] = trY - x;\n        }\n        break;\n      default:\n        throw new Error(\"Invalid rotation\");\n    }\n    return points;\n  }\n  static #fromPDFCoordinates(points, rect, rotation) {\n    const [blX, blY, trX, trY] = rect;\n    switch (rotation) {\n      case 0:\n        for (let i = 0, ii = points.length; i < ii; i += 2) {\n          points[i] -= blX;\n          points[i + 1] = trY - points[i + 1];\n        }\n        break;\n      case 90:\n        for (let i = 0, ii = points.length; i < ii; i += 2) {\n          const x = points[i];\n          points[i] = points[i + 1] - blY;\n          points[i + 1] = x - blX;\n        }\n        break;\n      case 180:\n        for (let i = 0, ii = points.length; i < ii; i += 2) {\n          points[i] = trX - points[i];\n          points[i + 1] -= blY;\n        }\n        break;\n      case 270:\n        for (let i = 0, ii = points.length; i < ii; i += 2) {\n          const x = points[i];\n          points[i] = trY - points[i + 1];\n          points[i + 1] = trX - x;\n        }\n        break;\n      default:\n        throw new Error(\"Invalid rotation\");\n    }\n    return points;\n  }\n  #serializePaths(s, tx, ty, rect) {\n    const paths = [];\n    const padding = this.thickness / 2;\n    const shiftX = s * tx + padding;\n    const shiftY = s * ty + padding;\n    for (const bezier of this.paths) {\n      const buffer = [];\n      const points = [];\n      for (let j = 0, jj = bezier.length; j < jj; j++) {\n        const [first, control1, control2, second] = bezier[j];\n        if (first[0] === second[0] && first[1] === second[1] && jj === 1) {\n          const p0 = s * first[0] + shiftX;\n          const p1 = s * first[1] + shiftY;\n          buffer.push(p0, p1);\n          points.push(p0, p1);\n          break;\n        }\n        const p10 = s * first[0] + shiftX;\n        const p11 = s * first[1] + shiftY;\n        const p20 = s * control1[0] + shiftX;\n        const p21 = s * control1[1] + shiftY;\n        const p30 = s * control2[0] + shiftX;\n        const p31 = s * control2[1] + shiftY;\n        const p40 = s * second[0] + shiftX;\n        const p41 = s * second[1] + shiftY;\n        if (j === 0) {\n          buffer.push(p10, p11);\n          points.push(p10, p11);\n        }\n        buffer.push(p20, p21, p30, p31, p40, p41);\n        points.push(p20, p21);\n        if (j === jj - 1) {\n          points.push(p40, p41);\n        }\n      }\n      paths.push({\n        bezier: InkEditor.#toPDFCoordinates(buffer, rect, this.rotation),\n        points: InkEditor.#toPDFCoordinates(points, rect, this.rotation)\n      });\n    }\n    return paths;\n  }\n  #getBbox() {\n    let xMin = Infinity;\n    let xMax = -Infinity;\n    let yMin = Infinity;\n    let yMax = -Infinity;\n    for (const path of this.paths) {\n      for (const [first, control1, control2, second] of path) {\n        const bbox = util.Util.bezierBoundingBox(...first, ...control1, ...control2, ...second);\n        xMin = Math.min(xMin, bbox[0]);\n        yMin = Math.min(yMin, bbox[1]);\n        xMax = Math.max(xMax, bbox[2]);\n        yMax = Math.max(yMax, bbox[3]);\n      }\n    }\n    return [xMin, yMin, xMax, yMax];\n  }\n  #getPadding() {\n    return this.#disableEditing ? Math.ceil(this.thickness * this.parentScale) : 0;\n  }\n  #fitToContent(firstTime = false) {\n    if (this.isEmpty()) {\n      return;\n    }\n    if (!this.#disableEditing) {\n      this.#redraw();\n      return;\n    }\n    const bbox = this.#getBbox();\n    const padding = this.#getPadding();\n    this.#baseWidth = Math.max(editor_editor.AnnotationEditor.MIN_SIZE, bbox[2] - bbox[0]);\n    this.#baseHeight = Math.max(editor_editor.AnnotationEditor.MIN_SIZE, bbox[3] - bbox[1]);\n    const width = Math.ceil(padding + this.#baseWidth * this.scaleFactor);\n    const height = Math.ceil(padding + this.#baseHeight * this.scaleFactor);\n    const [parentWidth, parentHeight] = this.parentDimensions;\n    this.width = width / parentWidth;\n    this.height = height / parentHeight;\n    this.setAspectRatio(width, height);\n    const prevTranslationX = this.translationX;\n    const prevTranslationY = this.translationY;\n    this.translationX = -bbox[0];\n    this.translationY = -bbox[1];\n    this.#setCanvasDims();\n    this.#redraw();\n    this.#realWidth = width;\n    this.#realHeight = height;\n    this.setDims(width, height);\n    const unscaledPadding = firstTime ? padding / this.scaleFactor / 2 : 0;\n    this.translate(prevTranslationX - this.translationX - unscaledPadding, prevTranslationY - this.translationY - unscaledPadding);\n  }\n  static deserialize(data, parent, uiManager) {\n    if (data instanceof annotation_layer.InkAnnotationElement) {\n      return null;\n    }\n    const editor = super.deserialize(data, parent, uiManager);\n    editor.thickness = data.thickness;\n    editor.color = util.Util.makeHexColor(...data.color);\n    editor.opacity = data.opacity;\n    const [pageWidth, pageHeight] = editor.pageDimensions;\n    const width = editor.width * pageWidth;\n    const height = editor.height * pageHeight;\n    const scaleFactor = editor.parentScale;\n    const padding = data.thickness / 2;\n    editor.#disableEditing = true;\n    editor.#realWidth = Math.round(width);\n    editor.#realHeight = Math.round(height);\n    const {\n      paths,\n      rect,\n      rotation\n    } = data;\n    for (let {\n      bezier\n    } of paths) {\n      bezier = InkEditor.#fromPDFCoordinates(bezier, rect, rotation);\n      const path = [];\n      editor.paths.push(path);\n      let p0 = scaleFactor * (bezier[0] - padding);\n      let p1 = scaleFactor * (bezier[1] - padding);\n      for (let i = 2, ii = bezier.length; i < ii; i += 6) {\n        const p10 = scaleFactor * (bezier[i] - padding);\n        const p11 = scaleFactor * (bezier[i + 1] - padding);\n        const p20 = scaleFactor * (bezier[i + 2] - padding);\n        const p21 = scaleFactor * (bezier[i + 3] - padding);\n        const p30 = scaleFactor * (bezier[i + 4] - padding);\n        const p31 = scaleFactor * (bezier[i + 5] - padding);\n        path.push([[p0, p1], [p10, p11], [p20, p21], [p30, p31]]);\n        p0 = p30;\n        p1 = p31;\n      }\n      const path2D = this.#buildPath2D(path);\n      editor.bezierPath2D.push(path2D);\n    }\n    const bbox = editor.#getBbox();\n    editor.#baseWidth = Math.max(editor_editor.AnnotationEditor.MIN_SIZE, bbox[2] - bbox[0]);\n    editor.#baseHeight = Math.max(editor_editor.AnnotationEditor.MIN_SIZE, bbox[3] - bbox[1]);\n    editor.#setScaleFactor(width, height);\n    return editor;\n  }\n  serialize() {\n    if (this.isEmpty()) {\n      return null;\n    }\n    const rect = this.getRect(0, 0);\n    const color = editor_editor.AnnotationEditor._colorManager.convert(this.ctx.strokeStyle);\n    return {\n      annotationType: util.AnnotationEditorType.INK,\n      color,\n      thickness: this.thickness,\n      opacity: this.opacity,\n      paths: this.#serializePaths(this.scaleFactor / this.parentScale, this.translationX, this.translationY, rect),\n      pageIndex: this.pageIndex,\n      rect,\n      rotation: this.rotation,\n      structTreeParentId: this._structTreeParentId\n    };\n  }\n}\n\n;// ./src/display/editor/stamp.js\n\n\n\n\nclass StampEditor extends editor_editor.AnnotationEditor {\n  #bitmap = null;\n  #bitmapId = null;\n  #bitmapPromise = null;\n  #bitmapUrl = null;\n  #bitmapFile = null;\n  #bitmapFileName = \"\";\n  #canvas = null;\n  #observer = null;\n  #resizeTimeoutId = null;\n  #isSvg = false;\n  #hasBeenAddedInUndoStack = false;\n  static _type = \"stamp\";\n  static _editorType = util.AnnotationEditorType.STAMP;\n  constructor(params) {\n    super({\n      ...params,\n      name: \"stampEditor\"\n    });\n    this.#bitmapUrl = params.bitmapUrl;\n    this.#bitmapFile = params.bitmapFile;\n  }\n  static initialize(l10n, uiManager) {\n    editor_editor.AnnotationEditor.initialize(l10n, uiManager);\n  }\n  static get supportedTypes() {\n    const types = [\"apng\", \"avif\", \"bmp\", \"gif\", \"jpeg\", \"png\", \"svg+xml\", \"webp\", \"x-icon\"];\n    return (0,util.shadow)(this, \"supportedTypes\", types.map(type => `image/${type}`));\n  }\n  static get supportedTypesStr() {\n    return (0,util.shadow)(this, \"supportedTypesStr\", this.supportedTypes.join(\",\"));\n  }\n  static isHandlingMimeForPasting(mime) {\n    return this.supportedTypes.includes(mime);\n  }\n  static paste(item, parent) {\n    parent.pasteEditor(util.AnnotationEditorType.STAMP, {\n      bitmapFile: item.getAsFile()\n    });\n  }\n  #getBitmapFetched(data, fromId = false) {\n    if (!data) {\n      this.remove();\n      return;\n    }\n    this.#bitmap = data.bitmap;\n    if (!fromId) {\n      this.#bitmapId = data.id;\n      this.#isSvg = data.isSvg;\n    }\n    if (data.file) {\n      this.#bitmapFileName = data.file.name;\n    }\n    this.#createCanvas();\n  }\n  #getBitmapDone() {\n    this.#bitmapPromise = null;\n    this._uiManager.enableWaiting(false);\n    if (this.#canvas) {\n      this.div.focus();\n    }\n  }\n  #getBitmap() {\n    if (this.#bitmapId) {\n      this._uiManager.enableWaiting(true);\n      this._uiManager.imageManager.getFromId(this.#bitmapId).then(data => this.#getBitmapFetched(data, true)).finally(() => this.#getBitmapDone());\n      return;\n    }\n    if (this.#bitmapUrl) {\n      const url = this.#bitmapUrl;\n      this.#bitmapUrl = null;\n      this._uiManager.enableWaiting(true);\n      this.#bitmapPromise = this._uiManager.imageManager.getFromUrl(url).then(data => this.#getBitmapFetched(data)).finally(() => this.#getBitmapDone());\n      return;\n    }\n    if (this.#bitmapFile) {\n      const file = this.#bitmapFile;\n      this.#bitmapFile = null;\n      this._uiManager.enableWaiting(true);\n      this.#bitmapPromise = this._uiManager.imageManager.getFromFile(file).then(data => this.#getBitmapFetched(data)).finally(() => this.#getBitmapDone());\n      return;\n    }\n    const input = document.createElement(\"input\");\n    input.type = \"file\";\n    input.accept = StampEditor.supportedTypesStr;\n    this.#bitmapPromise = new Promise(resolve => {\n      input.addEventListener(\"change\", async () => {\n        if (!input.files || input.files.length === 0) {\n          this.remove();\n        } else {\n          this._uiManager.enableWaiting(true);\n          const data = await this._uiManager.imageManager.getFromFile(input.files[0]);\n          this.#getBitmapFetched(data);\n        }\n        resolve();\n      });\n      input.addEventListener(\"cancel\", () => {\n        this.remove();\n        resolve();\n      });\n    }).finally(() => this.#getBitmapDone());\n    input.click();\n  }\n  remove() {\n    if (this.#bitmapId) {\n      this.#bitmap = null;\n      this._uiManager.imageManager.deleteId(this.#bitmapId);\n      this.#canvas?.remove();\n      this.#canvas = null;\n      this.#observer?.disconnect();\n      this.#observer = null;\n      if (this.#resizeTimeoutId) {\n        clearTimeout(this.#resizeTimeoutId);\n        this.#resizeTimeoutId = null;\n      }\n    }\n    super.remove();\n  }\n  rebuild() {\n    if (!this.parent) {\n      if (this.#bitmapId) {\n        this.#getBitmap();\n      }\n      return;\n    }\n    super.rebuild();\n    if (this.div === null) {\n      return;\n    }\n    if (this.#bitmapId) {\n      this.#getBitmap();\n    }\n    if (!this.isAttachedToDOM) {\n      this.parent.add(this);\n    }\n  }\n  onceAdded() {\n    this._isDraggable = true;\n    this.div.focus();\n  }\n  isEmpty() {\n    return !(this.#bitmapPromise || this.#bitmap || this.#bitmapUrl || this.#bitmapFile);\n  }\n  get isResizable() {\n    return true;\n  }\n  render() {\n    if (this.div) {\n      return this.div;\n    }\n    let baseX, baseY;\n    if (this.width) {\n      baseX = this.x;\n      baseY = this.y;\n    }\n    super.render();\n    this.div.hidden = true;\n    this.addAltTextButton();\n    if (this.#bitmap) {\n      this.#createCanvas();\n    } else {\n      this.#getBitmap();\n    }\n    if (this.width) {\n      const [parentWidth, parentHeight] = this.parentDimensions;\n      this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight);\n    }\n    return this.div;\n  }\n  #createCanvas() {\n    const {\n      div\n    } = this;\n    let {\n      width,\n      height\n    } = this.#bitmap;\n    const [pageWidth, pageHeight] = this.pageDimensions;\n    const MAX_RATIO = 0.75;\n    if (this.width) {\n      width = this.width * pageWidth;\n      height = this.height * pageHeight;\n    } else if (width > MAX_RATIO * pageWidth || height > MAX_RATIO * pageHeight) {\n      const factor = Math.min(MAX_RATIO * pageWidth / width, MAX_RATIO * pageHeight / height);\n      width *= factor;\n      height *= factor;\n    }\n    const [parentWidth, parentHeight] = this.parentDimensions;\n    this.setDims(width * parentWidth / pageWidth, height * parentHeight / pageHeight);\n    this._uiManager.enableWaiting(false);\n    const canvas = this.#canvas = document.createElement(\"canvas\");\n    div.append(canvas);\n    div.hidden = false;\n    this.#drawBitmap(width, height);\n    this.#createObserver();\n    if (!this.#hasBeenAddedInUndoStack) {\n      this.parent.addUndoableEditor(this);\n      this.#hasBeenAddedInUndoStack = true;\n    }\n    this._reportTelemetry({\n      action: \"inserted_image\"\n    });\n    if (this.#bitmapFileName) {\n      canvas.setAttribute(\"aria-label\", this.#bitmapFileName);\n    }\n  }\n  #setDimensions(width, height) {\n    const [parentWidth, parentHeight] = this.parentDimensions;\n    this.width = width / parentWidth;\n    this.height = height / parentHeight;\n    this.setDims(width, height);\n    if (this._initialOptions?.isCentered) {\n      this.center();\n    } else {\n      this.fixAndSetPosition();\n    }\n    this._initialOptions = null;\n    if (this.#resizeTimeoutId !== null) {\n      clearTimeout(this.#resizeTimeoutId);\n    }\n    const TIME_TO_WAIT = 200;\n    this.#resizeTimeoutId = setTimeout(() => {\n      this.#resizeTimeoutId = null;\n      this.#drawBitmap(width, height);\n    }, TIME_TO_WAIT);\n  }\n  #scaleBitmap(width, height) {\n    const {\n      width: bitmapWidth,\n      height: bitmapHeight\n    } = this.#bitmap;\n    let newWidth = bitmapWidth;\n    let newHeight = bitmapHeight;\n    let bitmap = this.#bitmap;\n    while (newWidth > 2 * width || newHeight > 2 * height) {\n      const prevWidth = newWidth;\n      const prevHeight = newHeight;\n      if (newWidth > 2 * width) {\n        newWidth = newWidth >= 16384 ? Math.floor(newWidth / 2) - 1 : Math.ceil(newWidth / 2);\n      }\n      if (newHeight > 2 * height) {\n        newHeight = newHeight >= 16384 ? Math.floor(newHeight / 2) - 1 : Math.ceil(newHeight / 2);\n      }\n      const offscreen = new OffscreenCanvas(newWidth, newHeight);\n      const ctx = offscreen.getContext(\"2d\");\n      ctx.drawImage(bitmap, 0, 0, prevWidth, prevHeight, 0, 0, newWidth, newHeight);\n      bitmap = offscreen.transferToImageBitmap();\n    }\n    return bitmap;\n  }\n  #drawBitmap(width, height) {\n    width = Math.ceil(width);\n    height = Math.ceil(height);\n    const canvas = this.#canvas;\n    if (!canvas || canvas.width === width && canvas.height === height) {\n      return;\n    }\n    canvas.width = width;\n    canvas.height = height;\n    const bitmap = this.#isSvg ? this.#bitmap : this.#scaleBitmap(width, height);\n    if (this._uiManager.hasMLManager && !this.hasAltText()) {\n      const offscreen = new OffscreenCanvas(width, height);\n      const ctx = offscreen.getContext(\"2d\");\n      ctx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, width, height);\n      offscreen.convertToBlob().then(blob => {\n        const fileReader = new FileReader();\n        fileReader.onload = () => {\n          const url = fileReader.result;\n          this._uiManager.mlGuess({\n            service: \"image-to-text\",\n            request: {\n              imageData: url\n            }\n          }).then(response => {\n            const altText = response?.output || \"\";\n            if (this.parent && altText && !this.hasAltText()) {\n              this.altTextData = {\n                altText,\n                decorative: false\n              };\n            }\n          });\n        };\n        fileReader.readAsDataURL(blob);\n      });\n    }\n    const ctx = canvas.getContext(\"2d\");\n    ctx.filter = this._uiManager.hcmFilter;\n    ctx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, width, height);\n  }\n  getImageForAltText() {\n    return this.#canvas;\n  }\n  #serializeBitmap(toUrl) {\n    if (toUrl) {\n      if (this.#isSvg) {\n        const url = this._uiManager.imageManager.getSvgUrl(this.#bitmapId);\n        if (url) {\n          return url;\n        }\n      }\n      const canvas = document.createElement(\"canvas\");\n      ({\n        width: canvas.width,\n        height: canvas.height\n      } = this.#bitmap);\n      const ctx = canvas.getContext(\"2d\");\n      ctx.drawImage(this.#bitmap, 0, 0);\n      return canvas.toDataURL();\n    }\n    if (this.#isSvg) {\n      const [pageWidth, pageHeight] = this.pageDimensions;\n      const width = Math.round(this.width * pageWidth * display_utils.PixelsPerInch.PDF_TO_CSS_UNITS);\n      const height = Math.round(this.height * pageHeight * display_utils.PixelsPerInch.PDF_TO_CSS_UNITS);\n      const offscreen = new OffscreenCanvas(width, height);\n      const ctx = offscreen.getContext(\"2d\");\n      ctx.drawImage(this.#bitmap, 0, 0, this.#bitmap.width, this.#bitmap.height, 0, 0, width, height);\n      return offscreen.transferToImageBitmap();\n    }\n    return structuredClone(this.#bitmap);\n  }\n  #createObserver() {\n    this.#observer = new ResizeObserver(entries => {\n      const rect = entries[0].contentRect;\n      if (rect.width && rect.height) {\n        this.#setDimensions(rect.width, rect.height);\n      }\n    });\n    this.#observer.observe(this.div);\n  }\n  static deserialize(data, parent, uiManager) {\n    if (data instanceof annotation_layer.StampAnnotationElement) {\n      return null;\n    }\n    const editor = super.deserialize(data, parent, uiManager);\n    const {\n      rect,\n      bitmapUrl,\n      bitmapId,\n      isSvg,\n      accessibilityData\n    } = data;\n    if (bitmapId && uiManager.imageManager.isValidId(bitmapId)) {\n      editor.#bitmapId = bitmapId;\n    } else {\n      editor.#bitmapUrl = bitmapUrl;\n    }\n    editor.#isSvg = isSvg;\n    const [parentWidth, parentHeight] = editor.pageDimensions;\n    editor.width = (rect[2] - rect[0]) / parentWidth;\n    editor.height = (rect[3] - rect[1]) / parentHeight;\n    if (accessibilityData) {\n      editor.altTextData = accessibilityData;\n    }\n    return editor;\n  }\n  serialize(isForCopying = false, context = null) {\n    if (this.isEmpty()) {\n      return null;\n    }\n    const serialized = {\n      annotationType: util.AnnotationEditorType.STAMP,\n      bitmapId: this.#bitmapId,\n      pageIndex: this.pageIndex,\n      rect: this.getRect(0, 0),\n      rotation: this.rotation,\n      isSvg: this.#isSvg,\n      structTreeParentId: this._structTreeParentId\n    };\n    if (isForCopying) {\n      serialized.bitmapUrl = this.#serializeBitmap(true);\n      serialized.accessibilityData = this.altTextData;\n      return serialized;\n    }\n    const {\n      decorative,\n      altText\n    } = this.altTextData;\n    if (!decorative && altText) {\n      serialized.accessibilityData = {\n        type: \"Figure\",\n        alt: altText\n      };\n    }\n    if (context === null) {\n      return serialized;\n    }\n    context.stamps ||= new Map();\n    const area = this.#isSvg ? (serialized.rect[2] - serialized.rect[0]) * (serialized.rect[3] - serialized.rect[1]) : null;\n    if (!context.stamps.has(this.#bitmapId)) {\n      context.stamps.set(this.#bitmapId, {\n        area,\n        serialized\n      });\n      serialized.bitmap = this.#serializeBitmap(false);\n    } else if (this.#isSvg) {\n      const prevData = context.stamps.get(this.#bitmapId);\n      if (area > prevData.area) {\n        prevData.area = area;\n        prevData.serialized.bitmap.close();\n        prevData.serialized.bitmap = this.#serializeBitmap(false);\n      }\n    }\n    return serialized;\n  }\n}\n\n;// ./src/display/editor/annotation_editor_layer.js\n\n\n\n\n\n\n\nclass AnnotationEditorLayer {\n  #accessibilityManager;\n  #allowClick = false;\n  #annotationLayer = null;\n  #boundPointerup = this.pointerup.bind(this);\n  #boundPointerdown = this.pointerdown.bind(this);\n  #boundTextLayerPointerDown = this.#textLayerPointerDown.bind(this);\n  #editorFocusTimeoutId = null;\n  #editors = new Map();\n  #hadPointerDown = false;\n  #isCleaningUp = false;\n  #isDisabling = false;\n  #textLayer = null;\n  #uiManager;\n  static _initialized = false;\n  static #editorTypes = new Map([FreeTextEditor, InkEditor, StampEditor, HighlightEditor].map(type => [type._editorType, type]));\n  constructor({\n    uiManager,\n    pageIndex,\n    div,\n    accessibilityManager,\n    annotationLayer,\n    drawLayer,\n    textLayer,\n    viewport,\n    l10n\n  }) {\n    const editorTypes = [...AnnotationEditorLayer.#editorTypes.values()];\n    if (!AnnotationEditorLayer._initialized) {\n      AnnotationEditorLayer._initialized = true;\n      for (const editorType of editorTypes) {\n        editorType.initialize(l10n, uiManager);\n      }\n    }\n    uiManager.registerEditorTypes(editorTypes);\n    this.#uiManager = uiManager;\n    this.pageIndex = pageIndex;\n    this.div = div;\n    this.#accessibilityManager = accessibilityManager;\n    this.#annotationLayer = annotationLayer;\n    this.viewport = viewport;\n    this.#textLayer = textLayer;\n    this.drawLayer = drawLayer;\n    this.#uiManager.addLayer(this);\n  }\n  get isEmpty() {\n    return this.#editors.size === 0;\n  }\n  updateToolbar(mode) {\n    this.#uiManager.updateToolbar(mode);\n  }\n  updateMode(mode = this.#uiManager.getMode()) {\n    this.#cleanup();\n    switch (mode) {\n      case util.AnnotationEditorType.NONE:\n        this.disableTextSelection();\n        this.togglePointerEvents(false);\n        this.toggleAnnotationLayerPointerEvents(true);\n        this.disableClick();\n        return;\n      case util.AnnotationEditorType.INK:\n        this.addInkEditorIfNeeded(false);\n        this.disableTextSelection();\n        this.togglePointerEvents(true);\n        this.disableClick();\n        break;\n      case util.AnnotationEditorType.HIGHLIGHT:\n        this.enableTextSelection();\n        this.togglePointerEvents(false);\n        this.disableClick();\n        break;\n      default:\n        this.disableTextSelection();\n        this.togglePointerEvents(true);\n        this.enableClick();\n    }\n    this.toggleAnnotationLayerPointerEvents(false);\n    const {\n      classList\n    } = this.div;\n    for (const editorType of AnnotationEditorLayer.#editorTypes.values()) {\n      classList.toggle(`${editorType._type}Editing`, mode === editorType._editorType);\n    }\n    this.div.hidden = false;\n  }\n  hasTextLayer(textLayer) {\n    return textLayer === this.#textLayer?.div;\n  }\n  addInkEditorIfNeeded(isCommitting) {\n    if (this.#uiManager.getMode() !== util.AnnotationEditorType.INK) {\n      return;\n    }\n    if (!isCommitting) {\n      for (const editor of this.#editors.values()) {\n        if (editor.isEmpty()) {\n          editor.setInBackground();\n          return;\n        }\n      }\n    }\n    const editor = this.createAndAddNewEditor({\n      offsetX: 0,\n      offsetY: 0\n    }, false);\n    editor.setInBackground();\n  }\n  setEditingState(isEditing) {\n    this.#uiManager.setEditingState(isEditing);\n  }\n  addCommands(params) {\n    this.#uiManager.addCommands(params);\n  }\n  togglePointerEvents(enabled = false) {\n    this.div.classList.toggle(\"disabled\", !enabled);\n  }\n  toggleAnnotationLayerPointerEvents(enabled = false) {\n    this.#annotationLayer?.div.classList.toggle(\"disabled\", !enabled);\n  }\n  enable() {\n    this.togglePointerEvents(true);\n    const annotationElementIds = new Set();\n    for (const editor of this.#editors.values()) {\n      editor.enableEditing();\n      if (editor.annotationElementId) {\n        annotationElementIds.add(editor.annotationElementId);\n      }\n    }\n    if (!this.#annotationLayer) {\n      return;\n    }\n    const editables = this.#annotationLayer.getEditableAnnotations();\n    for (const editable of editables) {\n      editable.hide();\n      if (this.#uiManager.isDeletedAnnotationElement(editable.data.id)) {\n        continue;\n      }\n      if (annotationElementIds.has(editable.data.id)) {\n        continue;\n      }\n      const editor = this.deserialize(editable);\n      if (!editor) {\n        continue;\n      }\n      this.addOrRebuild(editor);\n      editor.enableEditing();\n    }\n  }\n  disable() {\n    this.#isDisabling = true;\n    this.togglePointerEvents(false);\n    const hiddenAnnotationIds = new Set();\n    for (const editor of this.#editors.values()) {\n      editor.disableEditing();\n      if (!editor.annotationElementId || editor.serialize() !== null) {\n        hiddenAnnotationIds.add(editor.annotationElementId);\n        continue;\n      }\n      this.getEditableAnnotation(editor.annotationElementId)?.show();\n      editor.remove();\n    }\n    if (this.#annotationLayer) {\n      const editables = this.#annotationLayer.getEditableAnnotations();\n      for (const editable of editables) {\n        const {\n          id\n        } = editable.data;\n        if (hiddenAnnotationIds.has(id) || this.#uiManager.isDeletedAnnotationElement(id)) {\n          continue;\n        }\n        editable.show();\n      }\n    }\n    this.#cleanup();\n    if (this.isEmpty) {\n      this.div.hidden = true;\n    }\n    const {\n      classList\n    } = this.div;\n    for (const editorType of AnnotationEditorLayer.#editorTypes.values()) {\n      classList.remove(`${editorType._type}Editing`);\n    }\n    this.disableTextSelection();\n    this.toggleAnnotationLayerPointerEvents(true);\n    this.#isDisabling = false;\n  }\n  getEditableAnnotation(id) {\n    return this.#annotationLayer?.getEditableAnnotation(id) || null;\n  }\n  setActiveEditor(editor) {\n    const currentActive = this.#uiManager.getActive();\n    if (currentActive === editor) {\n      return;\n    }\n    this.#uiManager.setActiveEditor(editor);\n  }\n  enableTextSelection() {\n    if (this.#textLayer?.div) {\n      this.#textLayer.div.addEventListener(\"pointerdown\", this.#boundTextLayerPointerDown);\n      this.#textLayer.div.classList.add(\"highlighting\");\n    }\n  }\n  disableTextSelection() {\n    if (this.#textLayer?.div) {\n      this.#textLayer.div.removeEventListener(\"pointerdown\", this.#boundTextLayerPointerDown);\n      this.#textLayer.div.classList.remove(\"highlighting\");\n    }\n  }\n  #textLayerPointerDown(event) {\n    this.#uiManager.unselectAll();\n    if (event.target === this.#textLayer.div) {\n      const {\n        isMac\n      } = util.FeatureTest.platform;\n      if (event.button !== 0 || event.ctrlKey && isMac) {\n        return;\n      }\n      this.#uiManager.showAllEditors(\"highlight\", true, true);\n      this.#textLayer.div.classList.add(\"free\");\n      HighlightEditor.startHighlighting(this, this.#uiManager.direction === \"ltr\", event);\n      this.#textLayer.div.addEventListener(\"pointerup\", () => {\n        this.#textLayer.div.classList.remove(\"free\");\n      }, {\n        once: true\n      });\n      event.preventDefault();\n    }\n  }\n  enableClick() {\n    this.div.addEventListener(\"pointerdown\", this.#boundPointerdown);\n    this.div.addEventListener(\"pointerup\", this.#boundPointerup);\n  }\n  disableClick() {\n    this.div.removeEventListener(\"pointerdown\", this.#boundPointerdown);\n    this.div.removeEventListener(\"pointerup\", this.#boundPointerup);\n  }\n  attach(editor) {\n    this.#editors.set(editor.id, editor);\n    const {\n      annotationElementId\n    } = editor;\n    if (annotationElementId && this.#uiManager.isDeletedAnnotationElement(annotationElementId)) {\n      this.#uiManager.removeDeletedAnnotationElement(editor);\n    }\n  }\n  detach(editor) {\n    this.#editors.delete(editor.id);\n    this.#accessibilityManager?.removePointerInTextLayer(editor.contentDiv);\n    if (!this.#isDisabling && editor.annotationElementId) {\n      this.#uiManager.addDeletedAnnotationElement(editor);\n    }\n  }\n  remove(editor) {\n    this.detach(editor);\n    this.#uiManager.removeEditor(editor);\n    editor.div.remove();\n    editor.isAttachedToDOM = false;\n    if (!this.#isCleaningUp) {\n      this.addInkEditorIfNeeded(false);\n    }\n  }\n  changeParent(editor) {\n    if (editor.parent === this) {\n      return;\n    }\n    if (editor.annotationElementId) {\n      this.#uiManager.addDeletedAnnotationElement(editor.annotationElementId);\n      editor_editor.AnnotationEditor.deleteAnnotationElement(editor);\n      editor.annotationElementId = null;\n    }\n    this.attach(editor);\n    editor.parent?.detach(editor);\n    editor.setParent(this);\n    if (editor.div && editor.isAttachedToDOM) {\n      editor.div.remove();\n      this.div.append(editor.div);\n    }\n  }\n  add(editor) {\n    this.changeParent(editor);\n    this.#uiManager.addEditor(editor);\n    this.attach(editor);\n    if (!editor.isAttachedToDOM) {\n      const div = editor.render();\n      this.div.append(div);\n      editor.isAttachedToDOM = true;\n    }\n    editor.fixAndSetPosition();\n    editor.onceAdded();\n    this.#uiManager.addToAnnotationStorage(editor);\n    editor._reportTelemetry(editor.telemetryInitialData);\n  }\n  moveEditorInDOM(editor) {\n    if (!editor.isAttachedToDOM) {\n      return;\n    }\n    const {\n      activeElement\n    } = document;\n    if (editor.div.contains(activeElement) && !this.#editorFocusTimeoutId) {\n      editor._focusEventsAllowed = false;\n      this.#editorFocusTimeoutId = setTimeout(() => {\n        this.#editorFocusTimeoutId = null;\n        if (!editor.div.contains(document.activeElement)) {\n          editor.div.addEventListener(\"focusin\", () => {\n            editor._focusEventsAllowed = true;\n          }, {\n            once: true\n          });\n          activeElement.focus();\n        } else {\n          editor._focusEventsAllowed = true;\n        }\n      }, 0);\n    }\n    editor._structTreeParentId = this.#accessibilityManager?.moveElementInDOM(this.div, editor.div, editor.contentDiv, true);\n  }\n  addOrRebuild(editor) {\n    if (editor.needsToBeRebuilt()) {\n      editor.parent ||= this;\n      editor.rebuild();\n    } else {\n      this.add(editor);\n    }\n  }\n  addUndoableEditor(editor) {\n    const cmd = () => editor._uiManager.rebuild(editor);\n    const undo = () => {\n      editor.remove();\n    };\n    this.addCommands({\n      cmd,\n      undo,\n      mustExec: false\n    });\n  }\n  getNextId() {\n    return this.#uiManager.getId();\n  }\n  get #currentEditorType() {\n    return AnnotationEditorLayer.#editorTypes.get(this.#uiManager.getMode());\n  }\n  #createNewEditor(params) {\n    const editorType = this.#currentEditorType;\n    return editorType ? new editorType.prototype.constructor(params) : null;\n  }\n  canCreateNewEmptyEditor() {\n    return this.#currentEditorType?.canCreateNewEmptyEditor();\n  }\n  pasteEditor(mode, params) {\n    this.#uiManager.updateToolbar(mode);\n    this.#uiManager.updateMode(mode);\n    const {\n      offsetX,\n      offsetY\n    } = this.#getCenterPoint();\n    const id = this.getNextId();\n    const editor = this.#createNewEditor({\n      parent: this,\n      id,\n      x: offsetX,\n      y: offsetY,\n      uiManager: this.#uiManager,\n      isCentered: true,\n      ...params\n    });\n    if (editor) {\n      this.add(editor);\n    }\n  }\n  deserialize(data) {\n    return AnnotationEditorLayer.#editorTypes.get(data.annotationType ?? data.annotationEditorType)?.deserialize(data, this, this.#uiManager) || null;\n  }\n  createAndAddNewEditor(event, isCentered, data = {}) {\n    const id = this.getNextId();\n    const editor = this.#createNewEditor({\n      parent: this,\n      id,\n      x: event.offsetX,\n      y: event.offsetY,\n      uiManager: this.#uiManager,\n      isCentered,\n      ...data\n    });\n    if (editor) {\n      this.add(editor);\n    }\n    return editor;\n  }\n  #getCenterPoint() {\n    const {\n      x,\n      y,\n      width,\n      height\n    } = this.div.getBoundingClientRect();\n    const tlX = Math.max(0, x);\n    const tlY = Math.max(0, y);\n    const brX = Math.min(window.innerWidth, x + width);\n    const brY = Math.min(window.innerHeight, y + height);\n    const centerX = (tlX + brX) / 2 - x;\n    const centerY = (tlY + brY) / 2 - y;\n    const [offsetX, offsetY] = this.viewport.rotation % 180 === 0 ? [centerX, centerY] : [centerY, centerX];\n    return {\n      offsetX,\n      offsetY\n    };\n  }\n  addNewEditor() {\n    this.createAndAddNewEditor(this.#getCenterPoint(), true);\n  }\n  setSelected(editor) {\n    this.#uiManager.setSelected(editor);\n  }\n  toggleSelected(editor) {\n    this.#uiManager.toggleSelected(editor);\n  }\n  isSelected(editor) {\n    return this.#uiManager.isSelected(editor);\n  }\n  unselect(editor) {\n    this.#uiManager.unselect(editor);\n  }\n  pointerup(event) {\n    const {\n      isMac\n    } = util.FeatureTest.platform;\n    if (event.button !== 0 || event.ctrlKey && isMac) {\n      return;\n    }\n    if (event.target !== this.div) {\n      return;\n    }\n    if (!this.#hadPointerDown) {\n      return;\n    }\n    this.#hadPointerDown = false;\n    if (!this.#allowClick) {\n      this.#allowClick = true;\n      return;\n    }\n    if (this.#uiManager.getMode() === util.AnnotationEditorType.STAMP) {\n      this.#uiManager.unselectAll();\n      return;\n    }\n    this.createAndAddNewEditor(event, false);\n  }\n  pointerdown(event) {\n    if (this.#uiManager.getMode() === util.AnnotationEditorType.HIGHLIGHT) {\n      this.enableTextSelection();\n    }\n    if (this.#hadPointerDown) {\n      this.#hadPointerDown = false;\n      return;\n    }\n    const {\n      isMac\n    } = util.FeatureTest.platform;\n    if (event.button !== 0 || event.ctrlKey && isMac) {\n      return;\n    }\n    if (event.target !== this.div) {\n      return;\n    }\n    this.#hadPointerDown = true;\n    const editor = this.#uiManager.getActive();\n    this.#allowClick = !editor || editor.isEmpty();\n  }\n  findNewParent(editor, x, y) {\n    const layer = this.#uiManager.findParent(x, y);\n    if (layer === null || layer === this) {\n      return false;\n    }\n    layer.changeParent(editor);\n    return true;\n  }\n  destroy() {\n    if (this.#uiManager.getActive()?.parent === this) {\n      this.#uiManager.commitOrRemove();\n      this.#uiManager.setActiveEditor(null);\n    }\n    if (this.#editorFocusTimeoutId) {\n      clearTimeout(this.#editorFocusTimeoutId);\n      this.#editorFocusTimeoutId = null;\n    }\n    for (const editor of this.#editors.values()) {\n      this.#accessibilityManager?.removePointerInTextLayer(editor.contentDiv);\n      editor.setParent(null);\n      editor.isAttachedToDOM = false;\n      editor.div.remove();\n    }\n    this.div = null;\n    this.#editors.clear();\n    this.#uiManager.removeLayer(this);\n  }\n  #cleanup() {\n    this.#isCleaningUp = true;\n    for (const editor of this.#editors.values()) {\n      if (editor.isEmpty()) {\n        editor.remove();\n      }\n    }\n    this.#isCleaningUp = false;\n  }\n  render({\n    viewport\n  }) {\n    this.viewport = viewport;\n    (0,display_utils.setLayerDimensions)(this.div, viewport);\n    for (const editor of this.#uiManager.getEditors(this.pageIndex)) {\n      this.add(editor);\n    }\n    this.updateMode();\n  }\n  update({\n    viewport\n  }) {\n    this.#uiManager.commitOrRemove();\n    const oldRotation = this.viewport.rotation;\n    const rotation = viewport.rotation;\n    this.viewport = viewport;\n    (0,display_utils.setLayerDimensions)(this.div, {\n      rotation\n    });\n    if (oldRotation !== rotation) {\n      for (const editor of this.#editors.values()) {\n        editor.rotate(rotation);\n      }\n    }\n    this.updateMode();\n  }\n  get pageDimensions() {\n    const {\n      pageWidth,\n      pageHeight\n    } = this.viewport.rawDims;\n    return [pageWidth, pageHeight];\n  }\n  get scale() {\n    return this.#uiManager.viewParameters.realScale;\n  }\n}\n\n\n/***/ }),\n\n/***/ 786:\n/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   PDFNodeStream: () => (/* binding */ PDFNodeStream)\n/* harmony export */ });\n/* harmony import */ var _shared_util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(292);\n/* harmony import */ var _network_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(490);\n\n\nlet fs, http, https, url;\nif (_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.isNodeJS) {\n  fs = await import(/*webpackIgnore: true*/\"fs\");\n  http = await import(/*webpackIgnore: true*/\"http\");\n  https = await import(/*webpackIgnore: true*/\"https\");\n  url = await import(/*webpackIgnore: true*/\"url\");\n}\nconst fileUriRegex = /^file:\\/\\/\\/[a-zA-Z]:\\//;\nfunction parseUrl(sourceUrl) {\n  const parsedUrl = url.parse(sourceUrl);\n  if (parsedUrl.protocol === \"file:\" || parsedUrl.host) {\n    return parsedUrl;\n  }\n  if (/^[a-z]:[/\\\\]/i.test(sourceUrl)) {\n    return url.parse(`file:///${sourceUrl}`);\n  }\n  if (!parsedUrl.host) {\n    parsedUrl.protocol = \"file:\";\n  }\n  return parsedUrl;\n}\nclass PDFNodeStream {\n  constructor(source) {\n    this.source = source;\n    this.url = parseUrl(source.url);\n    this.isHttp = this.url.protocol === \"http:\" || this.url.protocol === \"https:\";\n    this.isFsUrl = this.url.protocol === \"file:\";\n    this.httpHeaders = this.isHttp && source.httpHeaders || {};\n    this._fullRequestReader = null;\n    this._rangeRequestReaders = [];\n  }\n  get _progressiveDataLength() {\n    return this._fullRequestReader?._loaded ?? 0;\n  }\n  getFullReader() {\n    (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.assert)(!this._fullRequestReader, \"PDFNodeStream.getFullReader can only be called once.\");\n    this._fullRequestReader = this.isFsUrl ? new PDFNodeStreamFsFullReader(this) : new PDFNodeStreamFullReader(this);\n    return this._fullRequestReader;\n  }\n  getRangeReader(start, end) {\n    if (end <= this._progressiveDataLength) {\n      return null;\n    }\n    const rangeReader = this.isFsUrl ? new PDFNodeStreamFsRangeReader(this, start, end) : new PDFNodeStreamRangeReader(this, start, end);\n    this._rangeRequestReaders.push(rangeReader);\n    return rangeReader;\n  }\n  cancelAllRequests(reason) {\n    this._fullRequestReader?.cancel(reason);\n    for (const reader of this._rangeRequestReaders.slice(0)) {\n      reader.cancel(reason);\n    }\n  }\n}\nclass BaseFullReader {\n  constructor(stream) {\n    this._url = stream.url;\n    this._done = false;\n    this._storedError = null;\n    this.onProgress = null;\n    const source = stream.source;\n    this._contentLength = source.length;\n    this._loaded = 0;\n    this._filename = null;\n    this._disableRange = source.disableRange || false;\n    this._rangeChunkSize = source.rangeChunkSize;\n    if (!this._rangeChunkSize && !this._disableRange) {\n      this._disableRange = true;\n    }\n    this._isStreamingSupported = !source.disableStream;\n    this._isRangeSupported = !source.disableRange;\n    this._readableStream = null;\n    this._readCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n    this._headersCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n  }\n  get headersReady() {\n    return this._headersCapability.promise;\n  }\n  get filename() {\n    return this._filename;\n  }\n  get contentLength() {\n    return this._contentLength;\n  }\n  get isRangeSupported() {\n    return this._isRangeSupported;\n  }\n  get isStreamingSupported() {\n    return this._isStreamingSupported;\n  }\n  async read() {\n    await this._readCapability.promise;\n    if (this._done) {\n      return {\n        value: undefined,\n        done: true\n      };\n    }\n    if (this._storedError) {\n      throw this._storedError;\n    }\n    const chunk = this._readableStream.read();\n    if (chunk === null) {\n      this._readCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n      return this.read();\n    }\n    this._loaded += chunk.length;\n    this.onProgress?.({\n      loaded: this._loaded,\n      total: this._contentLength\n    });\n    const buffer = new Uint8Array(chunk).buffer;\n    return {\n      value: buffer,\n      done: false\n    };\n  }\n  cancel(reason) {\n    if (!this._readableStream) {\n      this._error(reason);\n      return;\n    }\n    this._readableStream.destroy(reason);\n  }\n  _error(reason) {\n    this._storedError = reason;\n    this._readCapability.resolve();\n  }\n  _setReadableStream(readableStream) {\n    this._readableStream = readableStream;\n    readableStream.on(\"readable\", () => {\n      this._readCapability.resolve();\n    });\n    readableStream.on(\"end\", () => {\n      readableStream.destroy();\n      this._done = true;\n      this._readCapability.resolve();\n    });\n    readableStream.on(\"error\", reason => {\n      this._error(reason);\n    });\n    if (!this._isStreamingSupported && this._isRangeSupported) {\n      this._error(new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AbortException(\"streaming is disabled\"));\n    }\n    if (this._storedError) {\n      this._readableStream.destroy(this._storedError);\n    }\n  }\n}\nclass BaseRangeReader {\n  constructor(stream) {\n    this._url = stream.url;\n    this._done = false;\n    this._storedError = null;\n    this.onProgress = null;\n    this._loaded = 0;\n    this._readableStream = null;\n    this._readCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n    const source = stream.source;\n    this._isStreamingSupported = !source.disableStream;\n  }\n  get isStreamingSupported() {\n    return this._isStreamingSupported;\n  }\n  async read() {\n    await this._readCapability.promise;\n    if (this._done) {\n      return {\n        value: undefined,\n        done: true\n      };\n    }\n    if (this._storedError) {\n      throw this._storedError;\n    }\n    const chunk = this._readableStream.read();\n    if (chunk === null) {\n      this._readCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n      return this.read();\n    }\n    this._loaded += chunk.length;\n    this.onProgress?.({\n      loaded: this._loaded\n    });\n    const buffer = new Uint8Array(chunk).buffer;\n    return {\n      value: buffer,\n      done: false\n    };\n  }\n  cancel(reason) {\n    if (!this._readableStream) {\n      this._error(reason);\n      return;\n    }\n    this._readableStream.destroy(reason);\n  }\n  _error(reason) {\n    this._storedError = reason;\n    this._readCapability.resolve();\n  }\n  _setReadableStream(readableStream) {\n    this._readableStream = readableStream;\n    readableStream.on(\"readable\", () => {\n      this._readCapability.resolve();\n    });\n    readableStream.on(\"end\", () => {\n      readableStream.destroy();\n      this._done = true;\n      this._readCapability.resolve();\n    });\n    readableStream.on(\"error\", reason => {\n      this._error(reason);\n    });\n    if (this._storedError) {\n      this._readableStream.destroy(this._storedError);\n    }\n  }\n}\nfunction createRequestOptions(parsedUrl, headers) {\n  return {\n    protocol: parsedUrl.protocol,\n    auth: parsedUrl.auth,\n    host: parsedUrl.hostname,\n    port: parsedUrl.port,\n    path: parsedUrl.path,\n    method: \"GET\",\n    headers\n  };\n}\nclass PDFNodeStreamFullReader extends BaseFullReader {\n  constructor(stream) {\n    super(stream);\n    const handleResponse = response => {\n      if (response.statusCode === 404) {\n        const error = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.MissingPDFException(`Missing PDF \"${this._url}\".`);\n        this._storedError = error;\n        this._headersCapability.reject(error);\n        return;\n      }\n      this._headersCapability.resolve();\n      this._setReadableStream(response);\n      const getResponseHeader = name => this._readableStream.headers[name.toLowerCase()];\n      const {\n        allowRangeRequests,\n        suggestedLength\n      } = (0,_network_utils_js__WEBPACK_IMPORTED_MODULE_1__.validateRangeRequestCapabilities)({\n        getResponseHeader,\n        isHttp: stream.isHttp,\n        rangeChunkSize: this._rangeChunkSize,\n        disableRange: this._disableRange\n      });\n      this._isRangeSupported = allowRangeRequests;\n      this._contentLength = suggestedLength || this._contentLength;\n      this._filename = (0,_network_utils_js__WEBPACK_IMPORTED_MODULE_1__.extractFilenameFromHeader)(getResponseHeader);\n    };\n    this._request = null;\n    if (this._url.protocol === \"http:\") {\n      this._request = http.request(createRequestOptions(this._url, stream.httpHeaders), handleResponse);\n    } else {\n      this._request = https.request(createRequestOptions(this._url, stream.httpHeaders), handleResponse);\n    }\n    this._request.on(\"error\", reason => {\n      this._storedError = reason;\n      this._headersCapability.reject(reason);\n    });\n    this._request.end();\n  }\n}\nclass PDFNodeStreamRangeReader extends BaseRangeReader {\n  constructor(stream, start, end) {\n    super(stream);\n    this._httpHeaders = {};\n    for (const property in stream.httpHeaders) {\n      const value = stream.httpHeaders[property];\n      if (value === undefined) {\n        continue;\n      }\n      this._httpHeaders[property] = value;\n    }\n    this._httpHeaders.Range = `bytes=${start}-${end - 1}`;\n    const handleResponse = response => {\n      if (response.statusCode === 404) {\n        const error = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.MissingPDFException(`Missing PDF \"${this._url}\".`);\n        this._storedError = error;\n        return;\n      }\n      this._setReadableStream(response);\n    };\n    this._request = null;\n    if (this._url.protocol === \"http:\") {\n      this._request = http.request(createRequestOptions(this._url, this._httpHeaders), handleResponse);\n    } else {\n      this._request = https.request(createRequestOptions(this._url, this._httpHeaders), handleResponse);\n    }\n    this._request.on(\"error\", reason => {\n      this._storedError = reason;\n    });\n    this._request.end();\n  }\n}\nclass PDFNodeStreamFsFullReader extends BaseFullReader {\n  constructor(stream) {\n    super(stream);\n    let path = decodeURIComponent(this._url.path);\n    if (fileUriRegex.test(this._url.href)) {\n      path = path.replace(/^\\//, \"\");\n    }\n    fs.promises.lstat(path).then(stat => {\n      this._contentLength = stat.size;\n      this._setReadableStream(fs.createReadStream(path));\n      this._headersCapability.resolve();\n    }, error => {\n      if (error.code === \"ENOENT\") {\n        error = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.MissingPDFException(`Missing PDF \"${path}\".`);\n      }\n      this._storedError = error;\n      this._headersCapability.reject(error);\n    });\n  }\n}\nclass PDFNodeStreamFsRangeReader extends BaseRangeReader {\n  constructor(stream, start, end) {\n    super(stream);\n    let path = decodeURIComponent(this._url.path);\n    if (fileUriRegex.test(this._url.href)) {\n      path = path.replace(/^\\//, \"\");\n    }\n    this._setReadableStream(fs.createReadStream(path, {\n      start,\n      end: end - 1\n    }));\n  }\n}\n\n__webpack_async_result__();\n} catch(e) { __webpack_async_result__(e); } }, 1);\n\n/***/ }),\n\n/***/ 792:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   AnnotationStorage: () => (/* binding */ AnnotationStorage),\n/* harmony export */   PrintAnnotationStorage: () => (/* binding */ PrintAnnotationStorage),\n/* harmony export */   SerializableEmpty: () => (/* binding */ SerializableEmpty)\n/* harmony export */ });\n/* harmony import */ var _shared_util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(292);\n/* harmony import */ var _editor_editor_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(310);\n/* harmony import */ var _shared_murmurhash3_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(651);\n\n\n\nconst SerializableEmpty = Object.freeze({\n  map: null,\n  hash: \"\",\n  transfer: undefined\n});\nclass AnnotationStorage {\n  #modified = false;\n  #storage = new Map();\n  constructor() {\n    this.onSetModified = null;\n    this.onResetModified = null;\n    this.onAnnotationEditor = null;\n  }\n  getValue(key, defaultValue) {\n    const value = this.#storage.get(key);\n    if (value === undefined) {\n      return defaultValue;\n    }\n    return Object.assign(defaultValue, value);\n  }\n  getRawValue(key) {\n    return this.#storage.get(key);\n  }\n  remove(key) {\n    this.#storage.delete(key);\n    if (this.#storage.size === 0) {\n      this.resetModified();\n    }\n    if (typeof this.onAnnotationEditor === \"function\") {\n      for (const value of this.#storage.values()) {\n        if (value instanceof _editor_editor_js__WEBPACK_IMPORTED_MODULE_1__.AnnotationEditor) {\n          return;\n        }\n      }\n      this.onAnnotationEditor(null);\n    }\n  }\n  setValue(key, value) {\n    const obj = this.#storage.get(key);\n    let modified = false;\n    if (obj !== undefined) {\n      for (const [entry, val] of Object.entries(value)) {\n        if (obj[entry] !== val) {\n          modified = true;\n          obj[entry] = val;\n        }\n      }\n    } else {\n      modified = true;\n      this.#storage.set(key, value);\n    }\n    if (modified) {\n      this.#setModified();\n    }\n    if (value instanceof _editor_editor_js__WEBPACK_IMPORTED_MODULE_1__.AnnotationEditor && typeof this.onAnnotationEditor === \"function\") {\n      this.onAnnotationEditor(value.constructor._type);\n    }\n  }\n  has(key) {\n    return this.#storage.has(key);\n  }\n  getAll() {\n    return this.#storage.size > 0 ? (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.objectFromMap)(this.#storage) : null;\n  }\n  setAll(obj) {\n    for (const [key, val] of Object.entries(obj)) {\n      this.setValue(key, val);\n    }\n  }\n  get size() {\n    return this.#storage.size;\n  }\n  #setModified() {\n    if (!this.#modified) {\n      this.#modified = true;\n      if (typeof this.onSetModified === \"function\") {\n        this.onSetModified();\n      }\n    }\n  }\n  resetModified() {\n    if (this.#modified) {\n      this.#modified = false;\n      if (typeof this.onResetModified === \"function\") {\n        this.onResetModified();\n      }\n    }\n  }\n  get print() {\n    return new PrintAnnotationStorage(this);\n  }\n  get serializable() {\n    if (this.#storage.size === 0) {\n      return SerializableEmpty;\n    }\n    const map = new Map(),\n      hash = new _shared_murmurhash3_js__WEBPACK_IMPORTED_MODULE_2__.MurmurHash3_64(),\n      transfer = [];\n    const context = Object.create(null);\n    let hasBitmap = false;\n    for (const [key, val] of this.#storage) {\n      const serialized = val instanceof _editor_editor_js__WEBPACK_IMPORTED_MODULE_1__.AnnotationEditor ? val.serialize(false, context) : val;\n      if (serialized) {\n        map.set(key, serialized);\n        hash.update(`${key}:${JSON.stringify(serialized)}`);\n        hasBitmap ||= !!serialized.bitmap;\n      }\n    }\n    if (hasBitmap) {\n      for (const value of map.values()) {\n        if (value.bitmap) {\n          transfer.push(value.bitmap);\n        }\n      }\n    }\n    return map.size > 0 ? {\n      map,\n      hash: hash.hexdigest(),\n      transfer\n    } : SerializableEmpty;\n  }\n  get editorStats() {\n    let stats = null;\n    const typeToEditor = new Map();\n    for (const value of this.#storage.values()) {\n      if (!(value instanceof _editor_editor_js__WEBPACK_IMPORTED_MODULE_1__.AnnotationEditor)) {\n        continue;\n      }\n      const editorStats = value.telemetryFinalData;\n      if (!editorStats) {\n        continue;\n      }\n      const {\n        type\n      } = editorStats;\n      if (!typeToEditor.has(type)) {\n        typeToEditor.set(type, Object.getPrototypeOf(value).constructor);\n      }\n      stats ||= Object.create(null);\n      const map = stats[type] ||= new Map();\n      for (const [key, val] of Object.entries(editorStats)) {\n        if (key === \"type\") {\n          continue;\n        }\n        let counters = map.get(key);\n        if (!counters) {\n          counters = new Map();\n          map.set(key, counters);\n        }\n        const count = counters.get(val) ?? 0;\n        counters.set(val, count + 1);\n      }\n    }\n    for (const [type, editor] of typeToEditor) {\n      stats[type] = editor.computeTelemetryFinalData(stats[type]);\n    }\n    return stats;\n  }\n}\nclass PrintAnnotationStorage extends AnnotationStorage {\n  #serializable;\n  constructor(parent) {\n    super();\n    const {\n      map,\n      hash,\n      transfer\n    } = parent.serializable;\n    const clone = structuredClone(map, transfer ? {\n      transfer\n    } : null);\n    this.#serializable = {\n      map: clone,\n      hash,\n      transfer\n    };\n  }\n  get print() {\n    (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.unreachable)(\"Should not call PrintAnnotationStorage.print\");\n  }\n  get serializable() {\n    return this.#serializable;\n  }\n}\n\n\n/***/ }),\n\n/***/ 814:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   cleanupTextLayer: () => (/* binding */ cleanupTextLayer),\n/* harmony export */   renderTextLayer: () => (/* binding */ renderTextLayer),\n/* harmony export */   updateTextLayer: () => (/* binding */ updateTextLayer)\n/* harmony export */ });\n/* unused harmony export TextLayerRenderTask */\n/* harmony import */ var _shared_util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(292);\n/* harmony import */ var _display_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(419);\n\n\nconst MAX_TEXT_DIVS_TO_RENDER = 100000;\nconst DEFAULT_FONT_SIZE = 30;\nconst DEFAULT_FONT_ASCENT = 0.8;\nconst ascentCache = new Map();\nlet _canvasContext = null;\nfunction getCtx() {\n  if (!_canvasContext) {\n    const canvas = document.createElement(\"canvas\");\n    canvas.className = \"hiddenCanvasElement\";\n    document.body.append(canvas);\n    _canvasContext = canvas.getContext(\"2d\", {\n      alpha: false\n    });\n  }\n  return _canvasContext;\n}\nfunction cleanupTextLayer() {\n  _canvasContext?.canvas.remove();\n  _canvasContext = null;\n}\nfunction getAscent(fontFamily) {\n  const cachedAscent = ascentCache.get(fontFamily);\n  if (cachedAscent) {\n    return cachedAscent;\n  }\n  const ctx = getCtx();\n  const savedFont = ctx.font;\n  ctx.canvas.width = ctx.canvas.height = DEFAULT_FONT_SIZE;\n  ctx.font = `${DEFAULT_FONT_SIZE}px ${fontFamily}`;\n  const metrics = ctx.measureText(\"\");\n  let ascent = metrics.fontBoundingBoxAscent;\n  let descent = Math.abs(metrics.fontBoundingBoxDescent);\n  if (ascent) {\n    const ratio = ascent / (ascent + descent);\n    ascentCache.set(fontFamily, ratio);\n    ctx.canvas.width = ctx.canvas.height = 0;\n    ctx.font = savedFont;\n    return ratio;\n  }\n  ctx.strokeStyle = \"red\";\n  ctx.clearRect(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE);\n  ctx.strokeText(\"g\", 0, 0);\n  let pixels = ctx.getImageData(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE).data;\n  descent = 0;\n  for (let i = pixels.length - 1 - 3; i >= 0; i -= 4) {\n    if (pixels[i] > 0) {\n      descent = Math.ceil(i / 4 / DEFAULT_FONT_SIZE);\n      break;\n    }\n  }\n  ctx.clearRect(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE);\n  ctx.strokeText(\"A\", 0, DEFAULT_FONT_SIZE);\n  pixels = ctx.getImageData(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE).data;\n  ascent = 0;\n  for (let i = 0, ii = pixels.length; i < ii; i += 4) {\n    if (pixels[i] > 0) {\n      ascent = DEFAULT_FONT_SIZE - Math.floor(i / 4 / DEFAULT_FONT_SIZE);\n      break;\n    }\n  }\n  ctx.canvas.width = ctx.canvas.height = 0;\n  ctx.font = savedFont;\n  if (ascent) {\n    const ratio = ascent / (ascent + descent);\n    ascentCache.set(fontFamily, ratio);\n    return ratio;\n  }\n  ascentCache.set(fontFamily, DEFAULT_FONT_ASCENT);\n  return DEFAULT_FONT_ASCENT;\n}\nfunction appendText(task, geom, styles) {\n  const textDiv = document.createElement(\"span\");\n  const textDivProperties = {\n    angle: 0,\n    canvasWidth: 0,\n    hasText: geom.str !== \"\",\n    hasEOL: geom.hasEOL,\n    fontSize: 0\n  };\n  task._textDivs.push(textDiv);\n  const tx = _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.Util.transform(task._transform, geom.transform);\n  let angle = Math.atan2(tx[1], tx[0]);\n  const style = styles[geom.fontName];\n  if (style.vertical) {\n    angle += Math.PI / 2;\n  }\n  const fontFamily = task._fontInspectorEnabled && style.fontSubstitution || style.fontFamily;\n  const fontHeight = Math.hypot(tx[2], tx[3]);\n  const fontAscent = fontHeight * getAscent(fontFamily);\n  let left, top;\n  if (angle === 0) {\n    left = tx[4];\n    top = tx[5] - fontAscent;\n  } else {\n    left = tx[4] + fontAscent * Math.sin(angle);\n    top = tx[5] - fontAscent * Math.cos(angle);\n  }\n  const scaleFactorStr = \"calc(var(--scale-factor)*\";\n  const divStyle = textDiv.style;\n  if (task._container === task._rootContainer) {\n    divStyle.left = `${(100 * left / task._pageWidth).toFixed(2)}%`;\n    divStyle.top = `${(100 * top / task._pageHeight).toFixed(2)}%`;\n  } else {\n    divStyle.left = `${scaleFactorStr}${left.toFixed(2)}px)`;\n    divStyle.top = `${scaleFactorStr}${top.toFixed(2)}px)`;\n  }\n  divStyle.fontSize = `${scaleFactorStr}${fontHeight.toFixed(2)}px)`;\n  divStyle.fontFamily = fontFamily;\n  textDivProperties.fontSize = fontHeight;\n  textDiv.setAttribute(\"role\", \"presentation\");\n  textDiv.textContent = geom.str;\n  textDiv.dir = geom.dir;\n  if (task._fontInspectorEnabled) {\n    textDiv.dataset.fontName = style.fontSubstitutionLoadedName || geom.fontName;\n  }\n  if (angle !== 0) {\n    textDivProperties.angle = angle * (180 / Math.PI);\n  }\n  let shouldScaleText = false;\n  if (geom.str.length > 1) {\n    shouldScaleText = true;\n  } else if (geom.str !== \" \" && geom.transform[0] !== geom.transform[3]) {\n    const absScaleX = Math.abs(geom.transform[0]),\n      absScaleY = Math.abs(geom.transform[3]);\n    if (absScaleX !== absScaleY && Math.max(absScaleX, absScaleY) / Math.min(absScaleX, absScaleY) > 1.5) {\n      shouldScaleText = true;\n    }\n  }\n  if (shouldScaleText) {\n    textDivProperties.canvasWidth = style.vertical ? geom.height : geom.width;\n  }\n  task._textDivProperties.set(textDiv, textDivProperties);\n  if (task._isReadableStream) {\n    task._layoutText(textDiv);\n  }\n}\nfunction layout(params) {\n  const {\n    div,\n    scale,\n    properties,\n    ctx,\n    prevFontSize,\n    prevFontFamily\n  } = params;\n  const {\n    style\n  } = div;\n  let transform = \"\";\n  if (properties.canvasWidth !== 0 && properties.hasText) {\n    const {\n      fontFamily\n    } = style;\n    const {\n      canvasWidth,\n      fontSize\n    } = properties;\n    if (prevFontSize !== fontSize || prevFontFamily !== fontFamily) {\n      ctx.font = `${fontSize * scale}px ${fontFamily}`;\n      params.prevFontSize = fontSize;\n      params.prevFontFamily = fontFamily;\n    }\n    const {\n      width\n    } = ctx.measureText(div.textContent);\n    if (width > 0) {\n      transform = `scaleX(${canvasWidth * scale / width})`;\n    }\n  }\n  if (properties.angle !== 0) {\n    transform = `rotate(${properties.angle}deg) ${transform}`;\n  }\n  if (transform.length > 0) {\n    style.transform = transform;\n  }\n}\nfunction render(task) {\n  if (task._canceled) {\n    return;\n  }\n  const textDivs = task._textDivs;\n  const capability = task._capability;\n  const textDivsLength = textDivs.length;\n  if (textDivsLength > MAX_TEXT_DIVS_TO_RENDER) {\n    capability.resolve();\n    return;\n  }\n  if (!task._isReadableStream) {\n    for (const textDiv of textDivs) {\n      task._layoutText(textDiv);\n    }\n  }\n  capability.resolve();\n}\nclass TextLayerRenderTask {\n  constructor({\n    textContentSource,\n    container,\n    viewport,\n    textDivs,\n    textDivProperties,\n    textContentItemsStr\n  }) {\n    this._textContentSource = textContentSource;\n    this._isReadableStream = textContentSource instanceof ReadableStream;\n    this._container = this._rootContainer = container;\n    this._textDivs = textDivs || [];\n    this._textContentItemsStr = textContentItemsStr || [];\n    this._fontInspectorEnabled = !!globalThis.FontInspector?.enabled;\n    this._reader = null;\n    this._textDivProperties = textDivProperties || new WeakMap();\n    this._canceled = false;\n    this._capability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n    this._layoutTextParams = {\n      prevFontSize: null,\n      prevFontFamily: null,\n      div: null,\n      scale: viewport.scale * (globalThis.devicePixelRatio || 1),\n      properties: null,\n      ctx: getCtx()\n    };\n    const {\n      pageWidth,\n      pageHeight,\n      pageX,\n      pageY\n    } = viewport.rawDims;\n    this._transform = [1, 0, 0, -1, -pageX, pageY + pageHeight];\n    this._pageWidth = pageWidth;\n    this._pageHeight = pageHeight;\n    (0,_display_utils_js__WEBPACK_IMPORTED_MODULE_1__.setLayerDimensions)(container, viewport);\n    this._capability.promise.finally(() => {\n      this._layoutTextParams = null;\n    }).catch(() => {});\n  }\n  get promise() {\n    return this._capability.promise;\n  }\n  cancel() {\n    this._canceled = true;\n    if (this._reader) {\n      this._reader.cancel(new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AbortException(\"TextLayer task cancelled.\")).catch(() => {});\n      this._reader = null;\n    }\n    this._capability.reject(new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AbortException(\"TextLayer task cancelled.\"));\n  }\n  _processItems(items, styleCache) {\n    for (const item of items) {\n      if (item.str === undefined) {\n        if (item.type === \"beginMarkedContentProps\" || item.type === \"beginMarkedContent\") {\n          const parent = this._container;\n          this._container = document.createElement(\"span\");\n          this._container.classList.add(\"markedContent\");\n          if (item.id !== null) {\n            this._container.setAttribute(\"id\", `${item.id}`);\n          }\n          parent.append(this._container);\n        } else if (item.type === \"endMarkedContent\") {\n          this._container = this._container.parentNode;\n        }\n        continue;\n      }\n      this._textContentItemsStr.push(item.str);\n      appendText(this, item, styleCache);\n    }\n  }\n  _layoutText(textDiv) {\n    const textDivProperties = this._layoutTextParams.properties = this._textDivProperties.get(textDiv);\n    this._layoutTextParams.div = textDiv;\n    layout(this._layoutTextParams);\n    if (textDivProperties.hasText) {\n      this._container.append(textDiv);\n    }\n    if (textDivProperties.hasEOL) {\n      const br = document.createElement(\"br\");\n      br.setAttribute(\"role\", \"presentation\");\n      this._container.append(br);\n    }\n  }\n  _render() {\n    const capability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n    let styleCache = Object.create(null);\n    if (this._isReadableStream) {\n      const pump = () => {\n        this._reader.read().then(({\n          value,\n          done\n        }) => {\n          if (done) {\n            capability.resolve();\n            return;\n          }\n          Object.assign(styleCache, value.styles);\n          this._processItems(value.items, styleCache);\n          pump();\n        }, capability.reject);\n      };\n      this._reader = this._textContentSource.getReader();\n      pump();\n    } else if (this._textContentSource) {\n      const {\n        items,\n        styles\n      } = this._textContentSource;\n      this._processItems(items, styles);\n      capability.resolve();\n    } else {\n      throw new Error('No \"textContentSource\" parameter specified.');\n    }\n    capability.promise.then(() => {\n      styleCache = null;\n      render(this);\n    }, this._capability.reject);\n  }\n}\nfunction renderTextLayer(params) {\n  const task = new TextLayerRenderTask(params);\n  task._render();\n  return task;\n}\nfunction updateTextLayer({\n  container,\n  viewport,\n  textDivs,\n  textDivProperties,\n  mustRotate = true,\n  mustRescale = true\n}) {\n  if (mustRotate) {\n    (0,_display_utils_js__WEBPACK_IMPORTED_MODULE_1__.setLayerDimensions)(container, {\n      rotation: viewport.rotation\n    });\n  }\n  if (mustRescale) {\n    const ctx = getCtx();\n    const scale = viewport.scale * (globalThis.devicePixelRatio || 1);\n    const params = {\n      prevFontSize: null,\n      prevFontFamily: null,\n      div: null,\n      scale,\n      properties: null,\n      ctx\n    };\n    for (const div of textDivs) {\n      params.properties = textDivProperties.get(div);\n      params.div = div;\n      layout(params);\n    }\n  }\n}\n\n\n/***/ }),\n\n/***/ 830:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   AnnotationEditorUIManager: () => (/* binding */ AnnotationEditorUIManager),\n/* harmony export */   ColorManager: () => (/* binding */ ColorManager),\n/* harmony export */   KeyboardManager: () => (/* binding */ KeyboardManager),\n/* harmony export */   bindEvents: () => (/* binding */ bindEvents),\n/* harmony export */   opacityToHex: () => (/* binding */ opacityToHex)\n/* harmony export */ });\n/* unused harmony export CommandManager */\n/* harmony import */ var _shared_util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(292);\n/* harmony import */ var _display_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(419);\n/* harmony import */ var _toolbar_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(362);\n\n\n\nfunction bindEvents(obj, element, names) {\n  for (const name of names) {\n    element.addEventListener(name, obj[name].bind(obj));\n  }\n}\nfunction opacityToHex(opacity) {\n  return Math.round(Math.min(255, Math.max(1, 255 * opacity))).toString(16).padStart(2, \"0\");\n}\nclass IdManager {\n  #id = 0;\n  constructor() {}\n  get id() {\n    return `${_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorPrefix}${this.#id++}`;\n  }\n}\nclass ImageManager {\n  #baseId = (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.getUuid)();\n  #id = 0;\n  #cache = null;\n  static get _isSVGFittingCanvas() {\n    const svg = `data:image/svg+xml;charset=UTF-8,<svg viewBox=\"0 0 1 1\" width=\"1\" height=\"1\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"1\" height=\"1\" style=\"fill:red;\"/></svg>`;\n    const canvas = new OffscreenCanvas(1, 3);\n    const ctx = canvas.getContext(\"2d\");\n    const image = new Image();\n    image.src = svg;\n    const promise = image.decode().then(() => {\n      ctx.drawImage(image, 0, 0, 1, 1, 0, 0, 1, 3);\n      return new Uint32Array(ctx.getImageData(0, 0, 1, 1).data.buffer)[0] === 0;\n    });\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, \"_isSVGFittingCanvas\", promise);\n  }\n  async #get(key, rawData) {\n    this.#cache ||= new Map();\n    let data = this.#cache.get(key);\n    if (data === null) {\n      return null;\n    }\n    if (data?.bitmap) {\n      data.refCounter += 1;\n      return data;\n    }\n    try {\n      data ||= {\n        bitmap: null,\n        id: `image_${this.#baseId}_${this.#id++}`,\n        refCounter: 0,\n        isSvg: false\n      };\n      let image;\n      if (typeof rawData === \"string\") {\n        data.url = rawData;\n        image = await (0,_display_utils_js__WEBPACK_IMPORTED_MODULE_1__.fetchData)(rawData, \"blob\");\n      } else {\n        image = data.file = rawData;\n      }\n      if (image.type === \"image/svg+xml\") {\n        const mustRemoveAspectRatioPromise = ImageManager._isSVGFittingCanvas;\n        const fileReader = new FileReader();\n        const imageElement = new Image();\n        const imagePromise = new Promise((resolve, reject) => {\n          imageElement.onload = () => {\n            data.bitmap = imageElement;\n            data.isSvg = true;\n            resolve();\n          };\n          fileReader.onload = async () => {\n            const url = data.svgUrl = fileReader.result;\n            imageElement.src = (await mustRemoveAspectRatioPromise) ? `${url}#svgView(preserveAspectRatio(none))` : url;\n          };\n          imageElement.onerror = fileReader.onerror = reject;\n        });\n        fileReader.readAsDataURL(image);\n        await imagePromise;\n      } else {\n        data.bitmap = await createImageBitmap(image);\n      }\n      data.refCounter = 1;\n    } catch (e) {\n      console.error(e);\n      data = null;\n    }\n    this.#cache.set(key, data);\n    if (data) {\n      this.#cache.set(data.id, data);\n    }\n    return data;\n  }\n  async getFromFile(file) {\n    const {\n      lastModified,\n      name,\n      size,\n      type\n    } = file;\n    return this.#get(`${lastModified}_${name}_${size}_${type}`, file);\n  }\n  async getFromUrl(url) {\n    return this.#get(url, url);\n  }\n  async getFromId(id) {\n    this.#cache ||= new Map();\n    const data = this.#cache.get(id);\n    if (!data) {\n      return null;\n    }\n    if (data.bitmap) {\n      data.refCounter += 1;\n      return data;\n    }\n    if (data.file) {\n      return this.getFromFile(data.file);\n    }\n    return this.getFromUrl(data.url);\n  }\n  getSvgUrl(id) {\n    const data = this.#cache.get(id);\n    if (!data?.isSvg) {\n      return null;\n    }\n    return data.svgUrl;\n  }\n  deleteId(id) {\n    this.#cache ||= new Map();\n    const data = this.#cache.get(id);\n    if (!data) {\n      return;\n    }\n    data.refCounter -= 1;\n    if (data.refCounter !== 0) {\n      return;\n    }\n    data.bitmap = null;\n  }\n  isValidId(id) {\n    return id.startsWith(`image_${this.#baseId}_`);\n  }\n}\nclass CommandManager {\n  #commands = [];\n  #locked = false;\n  #maxSize;\n  #position = -1;\n  constructor(maxSize = 128) {\n    this.#maxSize = maxSize;\n  }\n  add({\n    cmd,\n    undo,\n    post,\n    mustExec,\n    type = NaN,\n    overwriteIfSameType = false,\n    keepUndo = false\n  }) {\n    if (mustExec) {\n      cmd();\n    }\n    if (this.#locked) {\n      return;\n    }\n    const save = {\n      cmd,\n      undo,\n      post,\n      type\n    };\n    if (this.#position === -1) {\n      if (this.#commands.length > 0) {\n        this.#commands.length = 0;\n      }\n      this.#position = 0;\n      this.#commands.push(save);\n      return;\n    }\n    if (overwriteIfSameType && this.#commands[this.#position].type === type) {\n      if (keepUndo) {\n        save.undo = this.#commands[this.#position].undo;\n      }\n      this.#commands[this.#position] = save;\n      return;\n    }\n    const next = this.#position + 1;\n    if (next === this.#maxSize) {\n      this.#commands.splice(0, 1);\n    } else {\n      this.#position = next;\n      if (next < this.#commands.length) {\n        this.#commands.splice(next);\n      }\n    }\n    this.#commands.push(save);\n  }\n  undo() {\n    if (this.#position === -1) {\n      return;\n    }\n    this.#locked = true;\n    const {\n      undo,\n      post\n    } = this.#commands[this.#position];\n    undo();\n    post?.();\n    this.#locked = false;\n    this.#position -= 1;\n  }\n  redo() {\n    if (this.#position < this.#commands.length - 1) {\n      this.#position += 1;\n      this.#locked = true;\n      const {\n        cmd,\n        post\n      } = this.#commands[this.#position];\n      cmd();\n      post?.();\n      this.#locked = false;\n    }\n  }\n  hasSomethingToUndo() {\n    return this.#position !== -1;\n  }\n  hasSomethingToRedo() {\n    return this.#position < this.#commands.length - 1;\n  }\n  destroy() {\n    this.#commands = null;\n  }\n}\nclass KeyboardManager {\n  constructor(callbacks) {\n    this.buffer = [];\n    this.callbacks = new Map();\n    this.allKeys = new Set();\n    const {\n      isMac\n    } = _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.FeatureTest.platform;\n    for (const [keys, callback, options = {}] of callbacks) {\n      for (const key of keys) {\n        const isMacKey = key.startsWith(\"mac+\");\n        if (isMac && isMacKey) {\n          this.callbacks.set(key.slice(4), {\n            callback,\n            options\n          });\n          this.allKeys.add(key.split(\"+\").at(-1));\n        } else if (!isMac && !isMacKey) {\n          this.callbacks.set(key, {\n            callback,\n            options\n          });\n          this.allKeys.add(key.split(\"+\").at(-1));\n        }\n      }\n    }\n  }\n  #serialize(event) {\n    if (event.altKey) {\n      this.buffer.push(\"alt\");\n    }\n    if (event.ctrlKey) {\n      this.buffer.push(\"ctrl\");\n    }\n    if (event.metaKey) {\n      this.buffer.push(\"meta\");\n    }\n    if (event.shiftKey) {\n      this.buffer.push(\"shift\");\n    }\n    this.buffer.push(event.key);\n    const str = this.buffer.join(\"+\");\n    this.buffer.length = 0;\n    return str;\n  }\n  exec(self, event) {\n    if (!this.allKeys.has(event.key)) {\n      return;\n    }\n    const info = this.callbacks.get(this.#serialize(event));\n    if (!info) {\n      return;\n    }\n    const {\n      callback,\n      options: {\n        bubbles = false,\n        args = [],\n        checker = null\n      }\n    } = info;\n    if (checker && !checker(self, event)) {\n      return;\n    }\n    callback.bind(self, ...args, event)();\n    if (!bubbles) {\n      event.stopPropagation();\n      event.preventDefault();\n    }\n  }\n}\nclass ColorManager {\n  static _colorsMapping = new Map([[\"CanvasText\", [0, 0, 0]], [\"Canvas\", [255, 255, 255]]]);\n  get _colors() {\n    const colors = new Map([[\"CanvasText\", null], [\"Canvas\", null]]);\n    (0,_display_utils_js__WEBPACK_IMPORTED_MODULE_1__.getColorValues)(colors);\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, \"_colors\", colors);\n  }\n  convert(color) {\n    const rgb = (0,_display_utils_js__WEBPACK_IMPORTED_MODULE_1__.getRGB)(color);\n    if (!window.matchMedia(\"(forced-colors: active)\").matches) {\n      return rgb;\n    }\n    for (const [name, RGB] of this._colors) {\n      if (RGB.every((x, i) => x === rgb[i])) {\n        return ColorManager._colorsMapping.get(name);\n      }\n    }\n    return rgb;\n  }\n  getHexCode(name) {\n    const rgb = this._colors.get(name);\n    if (!rgb) {\n      return name;\n    }\n    return _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.Util.makeHexColor(...rgb);\n  }\n}\nclass AnnotationEditorUIManager {\n  #activeEditor = null;\n  #allEditors = new Map();\n  #allLayers = new Map();\n  #altTextManager = null;\n  #annotationStorage = null;\n  #commandManager = new CommandManager();\n  #currentPageIndex = 0;\n  #deletedAnnotationsElementIds = new Set();\n  #draggingEditors = null;\n  #editorTypes = null;\n  #editorsToRescale = new Set();\n  #enableHighlightFloatingButton = false;\n  #filterFactory = null;\n  #focusMainContainerTimeoutId = null;\n  #highlightColors = null;\n  #highlightWhenShiftUp = false;\n  #highlightToolbar = null;\n  #idManager = new IdManager();\n  #isEnabled = false;\n  #isWaiting = false;\n  #lastActiveElement = null;\n  #mainHighlightColorPicker = null;\n  #mlManager = null;\n  #mode = _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE;\n  #selectedEditors = new Set();\n  #selectedTextNode = null;\n  #pageColors = null;\n  #showAllStates = null;\n  #boundBlur = this.blur.bind(this);\n  #boundFocus = this.focus.bind(this);\n  #boundCopy = this.copy.bind(this);\n  #boundCut = this.cut.bind(this);\n  #boundPaste = this.paste.bind(this);\n  #boundKeydown = this.keydown.bind(this);\n  #boundKeyup = this.keyup.bind(this);\n  #boundOnEditingAction = this.onEditingAction.bind(this);\n  #boundOnPageChanging = this.onPageChanging.bind(this);\n  #boundOnScaleChanging = this.onScaleChanging.bind(this);\n  #boundSelectionChange = this.#selectionChange.bind(this);\n  #boundOnRotationChanging = this.onRotationChanging.bind(this);\n  #previousStates = {\n    isEditing: false,\n    isEmpty: true,\n    hasSomethingToUndo: false,\n    hasSomethingToRedo: false,\n    hasSelectedEditor: false,\n    hasSelectedText: false\n  };\n  #translation = [0, 0];\n  #translationTimeoutId = null;\n  #container = null;\n  #viewer = null;\n  static TRANSLATE_SMALL = 1;\n  static TRANSLATE_BIG = 10;\n  static get _keyboardManager() {\n    const proto = AnnotationEditorUIManager.prototype;\n    const arrowChecker = self => self.#container.contains(document.activeElement) && document.activeElement.tagName !== \"BUTTON\" && self.hasSomethingToControl();\n    const textInputChecker = (_self, {\n      target: el\n    }) => {\n      if (el instanceof HTMLInputElement) {\n        const {\n          type\n        } = el;\n        return type !== \"text\" && type !== \"number\";\n      }\n      return true;\n    };\n    const small = this.TRANSLATE_SMALL;\n    const big = this.TRANSLATE_BIG;\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, \"_keyboardManager\", new KeyboardManager([[[\"ctrl+a\", \"mac+meta+a\"], proto.selectAll, {\n      checker: textInputChecker\n    }], [[\"ctrl+z\", \"mac+meta+z\"], proto.undo, {\n      checker: textInputChecker\n    }], [[\"ctrl+y\", \"ctrl+shift+z\", \"mac+meta+shift+z\", \"ctrl+shift+Z\", \"mac+meta+shift+Z\"], proto.redo, {\n      checker: textInputChecker\n    }], [[\"Backspace\", \"alt+Backspace\", \"ctrl+Backspace\", \"shift+Backspace\", \"mac+Backspace\", \"mac+alt+Backspace\", \"mac+ctrl+Backspace\", \"Delete\", \"ctrl+Delete\", \"shift+Delete\", \"mac+Delete\"], proto.delete, {\n      checker: textInputChecker\n    }], [[\"Enter\", \"mac+Enter\"], proto.addNewEditorFromKeyboard, {\n      checker: (self, {\n        target: el\n      }) => !(el instanceof HTMLButtonElement) && self.#container.contains(el) && !self.isEnterHandled\n    }], [[\" \", \"mac+ \"], proto.addNewEditorFromKeyboard, {\n      checker: (self, {\n        target: el\n      }) => !(el instanceof HTMLButtonElement) && self.#container.contains(document.activeElement)\n    }], [[\"Escape\", \"mac+Escape\"], proto.unselectAll], [[\"ArrowLeft\", \"mac+ArrowLeft\"], proto.translateSelectedEditors, {\n      args: [-small, 0],\n      checker: arrowChecker\n    }], [[\"ctrl+ArrowLeft\", \"mac+shift+ArrowLeft\"], proto.translateSelectedEditors, {\n      args: [-big, 0],\n      checker: arrowChecker\n    }], [[\"ArrowRight\", \"mac+ArrowRight\"], proto.translateSelectedEditors, {\n      args: [small, 0],\n      checker: arrowChecker\n    }], [[\"ctrl+ArrowRight\", \"mac+shift+ArrowRight\"], proto.translateSelectedEditors, {\n      args: [big, 0],\n      checker: arrowChecker\n    }], [[\"ArrowUp\", \"mac+ArrowUp\"], proto.translateSelectedEditors, {\n      args: [0, -small],\n      checker: arrowChecker\n    }], [[\"ctrl+ArrowUp\", \"mac+shift+ArrowUp\"], proto.translateSelectedEditors, {\n      args: [0, -big],\n      checker: arrowChecker\n    }], [[\"ArrowDown\", \"mac+ArrowDown\"], proto.translateSelectedEditors, {\n      args: [0, small],\n      checker: arrowChecker\n    }], [[\"ctrl+ArrowDown\", \"mac+shift+ArrowDown\"], proto.translateSelectedEditors, {\n      args: [0, big],\n      checker: arrowChecker\n    }]]));\n  }\n  constructor(container, viewer, altTextManager, eventBus, pdfDocument, pageColors, highlightColors, enableHighlightFloatingButton, mlManager) {\n    this.#container = container;\n    this.#viewer = viewer;\n    this.#altTextManager = altTextManager;\n    this._eventBus = eventBus;\n    this._eventBus._on(\"editingaction\", this.#boundOnEditingAction);\n    this._eventBus._on(\"pagechanging\", this.#boundOnPageChanging);\n    this._eventBus._on(\"scalechanging\", this.#boundOnScaleChanging);\n    this._eventBus._on(\"rotationchanging\", this.#boundOnRotationChanging);\n    this.#addSelectionListener();\n    this.#addKeyboardManager();\n    this.#annotationStorage = pdfDocument.annotationStorage;\n    this.#filterFactory = pdfDocument.filterFactory;\n    this.#pageColors = pageColors;\n    this.#highlightColors = highlightColors || null;\n    this.#enableHighlightFloatingButton = enableHighlightFloatingButton;\n    this.#mlManager = mlManager || null;\n    this.viewParameters = {\n      realScale: _display_utils_js__WEBPACK_IMPORTED_MODULE_1__.PixelsPerInch.PDF_TO_CSS_UNITS,\n      rotation: 0\n    };\n    this.isShiftKeyDown = false;\n  }\n  destroy() {\n    this.#removeKeyboardManager();\n    this.#removeFocusManager();\n    this._eventBus._off(\"editingaction\", this.#boundOnEditingAction);\n    this._eventBus._off(\"pagechanging\", this.#boundOnPageChanging);\n    this._eventBus._off(\"scalechanging\", this.#boundOnScaleChanging);\n    this._eventBus._off(\"rotationchanging\", this.#boundOnRotationChanging);\n    for (const layer of this.#allLayers.values()) {\n      layer.destroy();\n    }\n    this.#allLayers.clear();\n    this.#allEditors.clear();\n    this.#editorsToRescale.clear();\n    this.#activeEditor = null;\n    this.#selectedEditors.clear();\n    this.#commandManager.destroy();\n    this.#altTextManager?.destroy();\n    this.#highlightToolbar?.hide();\n    this.#highlightToolbar = null;\n    if (this.#focusMainContainerTimeoutId) {\n      clearTimeout(this.#focusMainContainerTimeoutId);\n      this.#focusMainContainerTimeoutId = null;\n    }\n    if (this.#translationTimeoutId) {\n      clearTimeout(this.#translationTimeoutId);\n      this.#translationTimeoutId = null;\n    }\n    this.#removeSelectionListener();\n  }\n  async mlGuess(data) {\n    return this.#mlManager?.guess(data) || null;\n  }\n  get hasMLManager() {\n    return !!this.#mlManager;\n  }\n  get hcmFilter() {\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, \"hcmFilter\", this.#pageColors ? this.#filterFactory.addHCMFilter(this.#pageColors.foreground, this.#pageColors.background) : \"none\");\n  }\n  get direction() {\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, \"direction\", getComputedStyle(this.#container).direction);\n  }\n  get highlightColors() {\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, \"highlightColors\", this.#highlightColors ? new Map(this.#highlightColors.split(\",\").map(pair => pair.split(\"=\").map(x => x.trim()))) : null);\n  }\n  get highlightColorNames() {\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, \"highlightColorNames\", this.highlightColors ? new Map(Array.from(this.highlightColors, e => e.reverse())) : null);\n  }\n  setMainHighlightColorPicker(colorPicker) {\n    this.#mainHighlightColorPicker = colorPicker;\n  }\n  editAltText(editor) {\n    this.#altTextManager?.editAltText(this, editor);\n  }\n  onPageChanging({\n    pageNumber\n  }) {\n    this.#currentPageIndex = pageNumber - 1;\n  }\n  focusMainContainer() {\n    this.#container.focus();\n  }\n  findParent(x, y) {\n    for (const layer of this.#allLayers.values()) {\n      const {\n        x: layerX,\n        y: layerY,\n        width,\n        height\n      } = layer.div.getBoundingClientRect();\n      if (x >= layerX && x <= layerX + width && y >= layerY && y <= layerY + height) {\n        return layer;\n      }\n    }\n    return null;\n  }\n  disableUserSelect(value = false) {\n    this.#viewer.classList.toggle(\"noUserSelect\", value);\n  }\n  addShouldRescale(editor) {\n    this.#editorsToRescale.add(editor);\n  }\n  removeShouldRescale(editor) {\n    this.#editorsToRescale.delete(editor);\n  }\n  onScaleChanging({\n    scale\n  }) {\n    this.commitOrRemove();\n    this.viewParameters.realScale = scale * _display_utils_js__WEBPACK_IMPORTED_MODULE_1__.PixelsPerInch.PDF_TO_CSS_UNITS;\n    for (const editor of this.#editorsToRescale) {\n      editor.onScaleChanging();\n    }\n  }\n  onRotationChanging({\n    pagesRotation\n  }) {\n    this.commitOrRemove();\n    this.viewParameters.rotation = pagesRotation;\n  }\n  #getAnchorElementForSelection({\n    anchorNode\n  }) {\n    return anchorNode.nodeType === Node.TEXT_NODE ? anchorNode.parentElement : anchorNode;\n  }\n  highlightSelection(methodOfCreation = \"\") {\n    const selection = document.getSelection();\n    if (!selection || selection.isCollapsed) {\n      return;\n    }\n    const {\n      anchorNode,\n      anchorOffset,\n      focusNode,\n      focusOffset\n    } = selection;\n    const text = selection.toString();\n    const anchorElement = this.#getAnchorElementForSelection(selection);\n    const textLayer = anchorElement.closest(\".textLayer\");\n    const boxes = this.getSelectionBoxes(textLayer);\n    if (!boxes) {\n      return;\n    }\n    selection.empty();\n    if (this.#mode === _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE) {\n      this._eventBus.dispatch(\"showannotationeditorui\", {\n        source: this,\n        mode: _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.HIGHLIGHT\n      });\n      this.showAllEditors(\"highlight\", true, true);\n    }\n    for (const layer of this.#allLayers.values()) {\n      if (layer.hasTextLayer(textLayer)) {\n        layer.createAndAddNewEditor({\n          x: 0,\n          y: 0\n        }, false, {\n          methodOfCreation,\n          boxes,\n          anchorNode,\n          anchorOffset,\n          focusNode,\n          focusOffset,\n          text\n        });\n        break;\n      }\n    }\n  }\n  #displayHighlightToolbar() {\n    const selection = document.getSelection();\n    if (!selection || selection.isCollapsed) {\n      return;\n    }\n    const anchorElement = this.#getAnchorElementForSelection(selection);\n    const textLayer = anchorElement.closest(\".textLayer\");\n    const boxes = this.getSelectionBoxes(textLayer);\n    if (!boxes) {\n      return;\n    }\n    this.#highlightToolbar ||= new _toolbar_js__WEBPACK_IMPORTED_MODULE_2__.HighlightToolbar(this);\n    this.#highlightToolbar.show(textLayer, boxes, this.direction === \"ltr\");\n  }\n  addToAnnotationStorage(editor) {\n    if (!editor.isEmpty() && this.#annotationStorage && !this.#annotationStorage.has(editor.id)) {\n      this.#annotationStorage.setValue(editor.id, editor);\n    }\n  }\n  #selectionChange() {\n    const selection = document.getSelection();\n    if (!selection || selection.isCollapsed) {\n      if (this.#selectedTextNode) {\n        this.#highlightToolbar?.hide();\n        this.#selectedTextNode = null;\n        this.#dispatchUpdateStates({\n          hasSelectedText: false\n        });\n      }\n      return;\n    }\n    const {\n      anchorNode\n    } = selection;\n    if (anchorNode === this.#selectedTextNode) {\n      return;\n    }\n    const anchorElement = this.#getAnchorElementForSelection(selection);\n    const textLayer = anchorElement.closest(\".textLayer\");\n    if (!textLayer) {\n      if (this.#selectedTextNode) {\n        this.#highlightToolbar?.hide();\n        this.#selectedTextNode = null;\n        this.#dispatchUpdateStates({\n          hasSelectedText: false\n        });\n      }\n      return;\n    }\n    this.#highlightToolbar?.hide();\n    this.#selectedTextNode = anchorNode;\n    this.#dispatchUpdateStates({\n      hasSelectedText: true\n    });\n    if (this.#mode !== _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.HIGHLIGHT && this.#mode !== _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE) {\n      return;\n    }\n    if (this.#mode === _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.HIGHLIGHT) {\n      this.showAllEditors(\"highlight\", true, true);\n    }\n    this.#highlightWhenShiftUp = this.isShiftKeyDown;\n    if (!this.isShiftKeyDown) {\n      const pointerup = e => {\n        if (e.type === \"pointerup\" && e.button !== 0) {\n          return;\n        }\n        window.removeEventListener(\"pointerup\", pointerup);\n        window.removeEventListener(\"blur\", pointerup);\n        if (e.type === \"pointerup\") {\n          this.#onSelectEnd(\"main_toolbar\");\n        }\n      };\n      window.addEventListener(\"pointerup\", pointerup);\n      window.addEventListener(\"blur\", pointerup);\n    }\n  }\n  #onSelectEnd(methodOfCreation = \"\") {\n    if (this.#mode === _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.HIGHLIGHT) {\n      this.highlightSelection(methodOfCreation);\n    } else if (this.#enableHighlightFloatingButton) {\n      this.#displayHighlightToolbar();\n    }\n  }\n  #addSelectionListener() {\n    document.addEventListener(\"selectionchange\", this.#boundSelectionChange);\n  }\n  #removeSelectionListener() {\n    document.removeEventListener(\"selectionchange\", this.#boundSelectionChange);\n  }\n  #addFocusManager() {\n    window.addEventListener(\"focus\", this.#boundFocus);\n    window.addEventListener(\"blur\", this.#boundBlur);\n  }\n  #removeFocusManager() {\n    window.removeEventListener(\"focus\", this.#boundFocus);\n    window.removeEventListener(\"blur\", this.#boundBlur);\n  }\n  blur() {\n    this.isShiftKeyDown = false;\n    if (this.#highlightWhenShiftUp) {\n      this.#highlightWhenShiftUp = false;\n      this.#onSelectEnd(\"main_toolbar\");\n    }\n    if (!this.hasSelection) {\n      return;\n    }\n    const {\n      activeElement\n    } = document;\n    for (const editor of this.#selectedEditors) {\n      if (editor.div.contains(activeElement)) {\n        this.#lastActiveElement = [editor, activeElement];\n        editor._focusEventsAllowed = false;\n        break;\n      }\n    }\n  }\n  focus() {\n    if (!this.#lastActiveElement) {\n      return;\n    }\n    const [lastEditor, lastActiveElement] = this.#lastActiveElement;\n    this.#lastActiveElement = null;\n    lastActiveElement.addEventListener(\"focusin\", () => {\n      lastEditor._focusEventsAllowed = true;\n    }, {\n      once: true\n    });\n    lastActiveElement.focus();\n  }\n  #addKeyboardManager() {\n    window.addEventListener(\"keydown\", this.#boundKeydown);\n    window.addEventListener(\"keyup\", this.#boundKeyup);\n  }\n  #removeKeyboardManager() {\n    window.removeEventListener(\"keydown\", this.#boundKeydown);\n    window.removeEventListener(\"keyup\", this.#boundKeyup);\n  }\n  #addCopyPasteListeners() {\n    document.addEventListener(\"copy\", this.#boundCopy);\n    document.addEventListener(\"cut\", this.#boundCut);\n    document.addEventListener(\"paste\", this.#boundPaste);\n  }\n  #removeCopyPasteListeners() {\n    document.removeEventListener(\"copy\", this.#boundCopy);\n    document.removeEventListener(\"cut\", this.#boundCut);\n    document.removeEventListener(\"paste\", this.#boundPaste);\n  }\n  addEditListeners() {\n    this.#addKeyboardManager();\n    this.#addCopyPasteListeners();\n  }\n  removeEditListeners() {\n    this.#removeKeyboardManager();\n    this.#removeCopyPasteListeners();\n  }\n  copy(event) {\n    event.preventDefault();\n    this.#activeEditor?.commitOrRemove();\n    if (!this.hasSelection) {\n      return;\n    }\n    const editors = [];\n    for (const editor of this.#selectedEditors) {\n      const serialized = editor.serialize(true);\n      if (serialized) {\n        editors.push(serialized);\n      }\n    }\n    if (editors.length === 0) {\n      return;\n    }\n    event.clipboardData.setData(\"application/pdfjs\", JSON.stringify(editors));\n  }\n  cut(event) {\n    this.copy(event);\n    this.delete();\n  }\n  paste(event) {\n    event.preventDefault();\n    const {\n      clipboardData\n    } = event;\n    for (const item of clipboardData.items) {\n      for (const editorType of this.#editorTypes) {\n        if (editorType.isHandlingMimeForPasting(item.type)) {\n          editorType.paste(item, this.currentLayer);\n          return;\n        }\n      }\n    }\n    let data = clipboardData.getData(\"application/pdfjs\");\n    if (!data) {\n      return;\n    }\n    try {\n      data = JSON.parse(data);\n    } catch (ex) {\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(`paste: \"${ex.message}\".`);\n      return;\n    }\n    if (!Array.isArray(data)) {\n      return;\n    }\n    this.unselectAll();\n    const layer = this.currentLayer;\n    try {\n      const newEditors = [];\n      for (const editor of data) {\n        const deserializedEditor = layer.deserialize(editor);\n        if (!deserializedEditor) {\n          return;\n        }\n        newEditors.push(deserializedEditor);\n      }\n      const cmd = () => {\n        for (const editor of newEditors) {\n          this.#addEditorToLayer(editor);\n        }\n        this.#selectEditors(newEditors);\n      };\n      const undo = () => {\n        for (const editor of newEditors) {\n          editor.remove();\n        }\n      };\n      this.addCommands({\n        cmd,\n        undo,\n        mustExec: true\n      });\n    } catch (ex) {\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(`paste: \"${ex.message}\".`);\n    }\n  }\n  keydown(event) {\n    if (!this.isShiftKeyDown && event.key === \"Shift\") {\n      this.isShiftKeyDown = true;\n    }\n    if (this.#mode !== _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE && !this.isEditorHandlingKeyboard) {\n      AnnotationEditorUIManager._keyboardManager.exec(this, event);\n    }\n  }\n  keyup(event) {\n    if (this.isShiftKeyDown && event.key === \"Shift\") {\n      this.isShiftKeyDown = false;\n      if (this.#highlightWhenShiftUp) {\n        this.#highlightWhenShiftUp = false;\n        this.#onSelectEnd(\"main_toolbar\");\n      }\n    }\n  }\n  onEditingAction({\n    name\n  }) {\n    switch (name) {\n      case \"undo\":\n      case \"redo\":\n      case \"delete\":\n      case \"selectAll\":\n        this[name]();\n        break;\n      case \"highlightSelection\":\n        this.highlightSelection(\"context_menu\");\n        break;\n    }\n  }\n  #dispatchUpdateStates(details) {\n    const hasChanged = Object.entries(details).some(([key, value]) => this.#previousStates[key] !== value);\n    if (hasChanged) {\n      this._eventBus.dispatch(\"annotationeditorstateschanged\", {\n        source: this,\n        details: Object.assign(this.#previousStates, details)\n      });\n      if (this.#mode === _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.HIGHLIGHT && details.hasSelectedEditor === false) {\n        this.#dispatchUpdateUI([[_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType.HIGHLIGHT_FREE, true]]);\n      }\n    }\n  }\n  #dispatchUpdateUI(details) {\n    this._eventBus.dispatch(\"annotationeditorparamschanged\", {\n      source: this,\n      details\n    });\n  }\n  setEditingState(isEditing) {\n    if (isEditing) {\n      this.#addFocusManager();\n      this.#addCopyPasteListeners();\n      this.#dispatchUpdateStates({\n        isEditing: this.#mode !== _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE,\n        isEmpty: this.#isEmpty(),\n        hasSomethingToUndo: this.#commandManager.hasSomethingToUndo(),\n        hasSomethingToRedo: this.#commandManager.hasSomethingToRedo(),\n        hasSelectedEditor: false\n      });\n    } else {\n      this.#removeFocusManager();\n      this.#removeCopyPasteListeners();\n      this.#dispatchUpdateStates({\n        isEditing: false\n      });\n      this.disableUserSelect(false);\n    }\n  }\n  registerEditorTypes(types) {\n    if (this.#editorTypes) {\n      return;\n    }\n    this.#editorTypes = types;\n    for (const editorType of this.#editorTypes) {\n      this.#dispatchUpdateUI(editorType.defaultPropertiesToUpdate);\n    }\n  }\n  getId() {\n    return this.#idManager.id;\n  }\n  get currentLayer() {\n    return this.#allLayers.get(this.#currentPageIndex);\n  }\n  getLayer(pageIndex) {\n    return this.#allLayers.get(pageIndex);\n  }\n  get currentPageIndex() {\n    return this.#currentPageIndex;\n  }\n  addLayer(layer) {\n    this.#allLayers.set(layer.pageIndex, layer);\n    if (this.#isEnabled) {\n      layer.enable();\n    } else {\n      layer.disable();\n    }\n  }\n  removeLayer(layer) {\n    this.#allLayers.delete(layer.pageIndex);\n  }\n  updateMode(mode, editId = null, isFromKeyboard = false) {\n    if (this.#mode === mode) {\n      return;\n    }\n    this.#mode = mode;\n    if (mode === _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE) {\n      this.setEditingState(false);\n      this.#disableAll();\n      return;\n    }\n    this.setEditingState(true);\n    this.#enableAll();\n    this.unselectAll();\n    for (const layer of this.#allLayers.values()) {\n      layer.updateMode(mode);\n    }\n    if (!editId && isFromKeyboard) {\n      this.addNewEditorFromKeyboard();\n      return;\n    }\n    if (!editId) {\n      return;\n    }\n    for (const editor of this.#allEditors.values()) {\n      if (editor.annotationElementId === editId) {\n        this.setSelected(editor);\n        editor.enterInEditMode();\n        break;\n      }\n    }\n  }\n  addNewEditorFromKeyboard() {\n    if (this.currentLayer.canCreateNewEmptyEditor()) {\n      this.currentLayer.addNewEditor();\n    }\n  }\n  updateToolbar(mode) {\n    if (mode === this.#mode) {\n      return;\n    }\n    this._eventBus.dispatch(\"switchannotationeditormode\", {\n      source: this,\n      mode\n    });\n  }\n  updateParams(type, value) {\n    if (!this.#editorTypes) {\n      return;\n    }\n    switch (type) {\n      case _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType.CREATE:\n        this.currentLayer.addNewEditor();\n        return;\n      case _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType.HIGHLIGHT_DEFAULT_COLOR:\n        this.#mainHighlightColorPicker?.updateColor(value);\n        break;\n      case _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType.HIGHLIGHT_SHOW_ALL:\n        this._eventBus.dispatch(\"reporttelemetry\", {\n          source: this,\n          details: {\n            type: \"editing\",\n            data: {\n              type: \"highlight\",\n              action: \"toggle_visibility\"\n            }\n          }\n        });\n        (this.#showAllStates ||= new Map()).set(type, value);\n        this.showAllEditors(\"highlight\", value);\n        break;\n    }\n    for (const editor of this.#selectedEditors) {\n      editor.updateParams(type, value);\n    }\n    for (const editorType of this.#editorTypes) {\n      editorType.updateDefaultParams(type, value);\n    }\n  }\n  showAllEditors(type, visible, updateButton = false) {\n    for (const editor of this.#allEditors.values()) {\n      if (editor.editorType === type) {\n        editor.show(visible);\n      }\n    }\n    const state = this.#showAllStates?.get(_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType.HIGHLIGHT_SHOW_ALL) ?? true;\n    if (state !== visible) {\n      this.#dispatchUpdateUI([[_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType.HIGHLIGHT_SHOW_ALL, visible]]);\n    }\n  }\n  enableWaiting(mustWait = false) {\n    if (this.#isWaiting === mustWait) {\n      return;\n    }\n    this.#isWaiting = mustWait;\n    for (const layer of this.#allLayers.values()) {\n      if (mustWait) {\n        layer.disableClick();\n      } else {\n        layer.enableClick();\n      }\n      layer.div.classList.toggle(\"waiting\", mustWait);\n    }\n  }\n  #enableAll() {\n    if (!this.#isEnabled) {\n      this.#isEnabled = true;\n      for (const layer of this.#allLayers.values()) {\n        layer.enable();\n      }\n    }\n  }\n  #disableAll() {\n    this.unselectAll();\n    if (this.#isEnabled) {\n      this.#isEnabled = false;\n      for (const layer of this.#allLayers.values()) {\n        layer.disable();\n      }\n    }\n  }\n  getEditors(pageIndex) {\n    const editors = [];\n    for (const editor of this.#allEditors.values()) {\n      if (editor.pageIndex === pageIndex) {\n        editors.push(editor);\n      }\n    }\n    return editors;\n  }\n  getEditor(id) {\n    return this.#allEditors.get(id);\n  }\n  addEditor(editor) {\n    this.#allEditors.set(editor.id, editor);\n  }\n  removeEditor(editor) {\n    if (editor.div.contains(document.activeElement)) {\n      if (this.#focusMainContainerTimeoutId) {\n        clearTimeout(this.#focusMainContainerTimeoutId);\n      }\n      this.#focusMainContainerTimeoutId = setTimeout(() => {\n        this.focusMainContainer();\n        this.#focusMainContainerTimeoutId = null;\n      }, 0);\n    }\n    this.#allEditors.delete(editor.id);\n    this.unselect(editor);\n    if (!editor.annotationElementId || !this.#deletedAnnotationsElementIds.has(editor.annotationElementId)) {\n      this.#annotationStorage?.remove(editor.id);\n    }\n  }\n  addDeletedAnnotationElement(editor) {\n    this.#deletedAnnotationsElementIds.add(editor.annotationElementId);\n    editor.deleted = true;\n  }\n  isDeletedAnnotationElement(annotationElementId) {\n    return this.#deletedAnnotationsElementIds.has(annotationElementId);\n  }\n  removeDeletedAnnotationElement(editor) {\n    this.#deletedAnnotationsElementIds.delete(editor.annotationElementId);\n    editor.deleted = false;\n  }\n  #addEditorToLayer(editor) {\n    const layer = this.#allLayers.get(editor.pageIndex);\n    if (layer) {\n      layer.addOrRebuild(editor);\n    } else {\n      this.addEditor(editor);\n    }\n  }\n  setActiveEditor(editor) {\n    if (this.#activeEditor === editor) {\n      return;\n    }\n    this.#activeEditor = editor;\n    if (editor) {\n      this.#dispatchUpdateUI(editor.propertiesToUpdate);\n    }\n  }\n  get #lastSelectedEditor() {\n    let ed = null;\n    for (ed of this.#selectedEditors) {}\n    return ed;\n  }\n  updateUI(editor) {\n    if (this.#lastSelectedEditor === editor) {\n      this.#dispatchUpdateUI(editor.propertiesToUpdate);\n    }\n  }\n  toggleSelected(editor) {\n    if (this.#selectedEditors.has(editor)) {\n      this.#selectedEditors.delete(editor);\n      editor.unselect();\n      this.#dispatchUpdateStates({\n        hasSelectedEditor: this.hasSelection\n      });\n      return;\n    }\n    this.#selectedEditors.add(editor);\n    editor.select();\n    this.#dispatchUpdateUI(editor.propertiesToUpdate);\n    this.#dispatchUpdateStates({\n      hasSelectedEditor: true\n    });\n  }\n  setSelected(editor) {\n    for (const ed of this.#selectedEditors) {\n      if (ed !== editor) {\n        ed.unselect();\n      }\n    }\n    this.#selectedEditors.clear();\n    this.#selectedEditors.add(editor);\n    editor.select();\n    this.#dispatchUpdateUI(editor.propertiesToUpdate);\n    this.#dispatchUpdateStates({\n      hasSelectedEditor: true\n    });\n  }\n  isSelected(editor) {\n    return this.#selectedEditors.has(editor);\n  }\n  get firstSelectedEditor() {\n    return this.#selectedEditors.values().next().value;\n  }\n  unselect(editor) {\n    editor.unselect();\n    this.#selectedEditors.delete(editor);\n    this.#dispatchUpdateStates({\n      hasSelectedEditor: this.hasSelection\n    });\n  }\n  get hasSelection() {\n    return this.#selectedEditors.size !== 0;\n  }\n  get isEnterHandled() {\n    return this.#selectedEditors.size === 1 && this.firstSelectedEditor.isEnterHandled;\n  }\n  undo() {\n    this.#commandManager.undo();\n    this.#dispatchUpdateStates({\n      hasSomethingToUndo: this.#commandManager.hasSomethingToUndo(),\n      hasSomethingToRedo: true,\n      isEmpty: this.#isEmpty()\n    });\n  }\n  redo() {\n    this.#commandManager.redo();\n    this.#dispatchUpdateStates({\n      hasSomethingToUndo: true,\n      hasSomethingToRedo: this.#commandManager.hasSomethingToRedo(),\n      isEmpty: this.#isEmpty()\n    });\n  }\n  addCommands(params) {\n    this.#commandManager.add(params);\n    this.#dispatchUpdateStates({\n      hasSomethingToUndo: true,\n      hasSomethingToRedo: false,\n      isEmpty: this.#isEmpty()\n    });\n  }\n  #isEmpty() {\n    if (this.#allEditors.size === 0) {\n      return true;\n    }\n    if (this.#allEditors.size === 1) {\n      for (const editor of this.#allEditors.values()) {\n        return editor.isEmpty();\n      }\n    }\n    return false;\n  }\n  delete() {\n    this.commitOrRemove();\n    if (!this.hasSelection) {\n      return;\n    }\n    const editors = [...this.#selectedEditors];\n    const cmd = () => {\n      for (const editor of editors) {\n        editor.remove();\n      }\n    };\n    const undo = () => {\n      for (const editor of editors) {\n        this.#addEditorToLayer(editor);\n      }\n    };\n    this.addCommands({\n      cmd,\n      undo,\n      mustExec: true\n    });\n  }\n  commitOrRemove() {\n    this.#activeEditor?.commitOrRemove();\n  }\n  hasSomethingToControl() {\n    return this.#activeEditor || this.hasSelection;\n  }\n  #selectEditors(editors) {\n    for (const editor of this.#selectedEditors) {\n      editor.unselect();\n    }\n    this.#selectedEditors.clear();\n    for (const editor of editors) {\n      if (editor.isEmpty()) {\n        continue;\n      }\n      this.#selectedEditors.add(editor);\n      editor.select();\n    }\n    this.#dispatchUpdateStates({\n      hasSelectedEditor: this.hasSelection\n    });\n  }\n  selectAll() {\n    for (const editor of this.#selectedEditors) {\n      editor.commit();\n    }\n    this.#selectEditors(this.#allEditors.values());\n  }\n  unselectAll() {\n    if (this.#activeEditor) {\n      this.#activeEditor.commitOrRemove();\n      if (this.#mode !== _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE) {\n        return;\n      }\n    }\n    if (!this.hasSelection) {\n      return;\n    }\n    for (const editor of this.#selectedEditors) {\n      editor.unselect();\n    }\n    this.#selectedEditors.clear();\n    this.#dispatchUpdateStates({\n      hasSelectedEditor: false\n    });\n  }\n  translateSelectedEditors(x, y, noCommit = false) {\n    if (!noCommit) {\n      this.commitOrRemove();\n    }\n    if (!this.hasSelection) {\n      return;\n    }\n    this.#translation[0] += x;\n    this.#translation[1] += y;\n    const [totalX, totalY] = this.#translation;\n    const editors = [...this.#selectedEditors];\n    const TIME_TO_WAIT = 1000;\n    if (this.#translationTimeoutId) {\n      clearTimeout(this.#translationTimeoutId);\n    }\n    this.#translationTimeoutId = setTimeout(() => {\n      this.#translationTimeoutId = null;\n      this.#translation[0] = this.#translation[1] = 0;\n      this.addCommands({\n        cmd: () => {\n          for (const editor of editors) {\n            if (this.#allEditors.has(editor.id)) {\n              editor.translateInPage(totalX, totalY);\n            }\n          }\n        },\n        undo: () => {\n          for (const editor of editors) {\n            if (this.#allEditors.has(editor.id)) {\n              editor.translateInPage(-totalX, -totalY);\n            }\n          }\n        },\n        mustExec: false\n      });\n    }, TIME_TO_WAIT);\n    for (const editor of editors) {\n      editor.translateInPage(x, y);\n    }\n  }\n  setUpDragSession() {\n    if (!this.hasSelection) {\n      return;\n    }\n    this.disableUserSelect(true);\n    this.#draggingEditors = new Map();\n    for (const editor of this.#selectedEditors) {\n      this.#draggingEditors.set(editor, {\n        savedX: editor.x,\n        savedY: editor.y,\n        savedPageIndex: editor.pageIndex,\n        newX: 0,\n        newY: 0,\n        newPageIndex: -1\n      });\n    }\n  }\n  endDragSession() {\n    if (!this.#draggingEditors) {\n      return false;\n    }\n    this.disableUserSelect(false);\n    const map = this.#draggingEditors;\n    this.#draggingEditors = null;\n    let mustBeAddedInUndoStack = false;\n    for (const [{\n      x,\n      y,\n      pageIndex\n    }, value] of map) {\n      value.newX = x;\n      value.newY = y;\n      value.newPageIndex = pageIndex;\n      mustBeAddedInUndoStack ||= x !== value.savedX || y !== value.savedY || pageIndex !== value.savedPageIndex;\n    }\n    if (!mustBeAddedInUndoStack) {\n      return false;\n    }\n    const move = (editor, x, y, pageIndex) => {\n      if (this.#allEditors.has(editor.id)) {\n        const parent = this.#allLayers.get(pageIndex);\n        if (parent) {\n          editor._setParentAndPosition(parent, x, y);\n        } else {\n          editor.pageIndex = pageIndex;\n          editor.x = x;\n          editor.y = y;\n        }\n      }\n    };\n    this.addCommands({\n      cmd: () => {\n        for (const [editor, {\n          newX,\n          newY,\n          newPageIndex\n        }] of map) {\n          move(editor, newX, newY, newPageIndex);\n        }\n      },\n      undo: () => {\n        for (const [editor, {\n          savedX,\n          savedY,\n          savedPageIndex\n        }] of map) {\n          move(editor, savedX, savedY, savedPageIndex);\n        }\n      },\n      mustExec: true\n    });\n    return true;\n  }\n  dragSelectedEditors(tx, ty) {\n    if (!this.#draggingEditors) {\n      return;\n    }\n    for (const editor of this.#draggingEditors.keys()) {\n      editor.drag(tx, ty);\n    }\n  }\n  rebuild(editor) {\n    if (editor.parent === null) {\n      const parent = this.getLayer(editor.pageIndex);\n      if (parent) {\n        parent.changeParent(editor);\n        parent.addOrRebuild(editor);\n      } else {\n        this.addEditor(editor);\n        this.addToAnnotationStorage(editor);\n        editor.rebuild();\n      }\n    } else {\n      editor.parent.addOrRebuild(editor);\n    }\n  }\n  get isEditorHandlingKeyboard() {\n    return this.getActive()?.shouldGetKeyboardEvents() || this.#selectedEditors.size === 1 && this.firstSelectedEditor.shouldGetKeyboardEvents();\n  }\n  isActive(editor) {\n    return this.#activeEditor === editor;\n  }\n  getActive() {\n    return this.#activeEditor;\n  }\n  getMode() {\n    return this.#mode;\n  }\n  get imageManager() {\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, \"imageManager\", new ImageManager());\n  }\n  getSelectionBoxes(textLayer) {\n    if (!textLayer) {\n      return null;\n    }\n    const selection = document.getSelection();\n    for (let i = 0, ii = selection.rangeCount; i < ii; i++) {\n      if (!textLayer.contains(selection.getRangeAt(i).commonAncestorContainer)) {\n        return null;\n      }\n    }\n    const {\n      x: layerX,\n      y: layerY,\n      width: parentWidth,\n      height: parentHeight\n    } = textLayer.getBoundingClientRect();\n    let rotator;\n    switch (textLayer.getAttribute(\"data-main-rotation\")) {\n      case \"90\":\n        rotator = (x, y, w, h) => ({\n          x: (y - layerY) / parentHeight,\n          y: 1 - (x + w - layerX) / parentWidth,\n          width: h / parentHeight,\n          height: w / parentWidth\n        });\n        break;\n      case \"180\":\n        rotator = (x, y, w, h) => ({\n          x: 1 - (x + w - layerX) / parentWidth,\n          y: 1 - (y + h - layerY) / parentHeight,\n          width: w / parentWidth,\n          height: h / parentHeight\n        });\n        break;\n      case \"270\":\n        rotator = (x, y, w, h) => ({\n          x: 1 - (y + h - layerY) / parentHeight,\n          y: (x - layerX) / parentWidth,\n          width: h / parentHeight,\n          height: w / parentWidth\n        });\n        break;\n      default:\n        rotator = (x, y, w, h) => ({\n          x: (x - layerX) / parentWidth,\n          y: (y - layerY) / parentHeight,\n          width: w / parentWidth,\n          height: h / parentHeight\n        });\n        break;\n    }\n    const boxes = [];\n    for (let i = 0, ii = selection.rangeCount; i < ii; i++) {\n      const range = selection.getRangeAt(i);\n      if (range.collapsed) {\n        continue;\n      }\n      for (const {\n        x,\n        y,\n        width,\n        height\n      } of range.getClientRects()) {\n        if (width === 0 || height === 0) {\n          continue;\n        }\n        boxes.push(rotator(x, y, width, height));\n      }\n    }\n    return boxes.length === 0 ? null : boxes;\n  }\n}\n\n\n/***/ }),\n\n/***/ 831:\n/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   PDFDataRangeTransport: () => (/* binding */ PDFDataRangeTransport),\n/* harmony export */   PDFWorker: () => (/* binding */ PDFWorker),\n/* harmony export */   build: () => (/* binding */ build),\n/* harmony export */   getDocument: () => (/* binding */ getDocument),\n/* harmony export */   version: () => (/* binding */ version)\n/* harmony export */ });\n/* unused harmony exports DefaultCanvasFactory, DefaultCMapReaderFactory, DefaultFilterFactory, DefaultStandardFontDataFactory, LoopbackPort, PDFDocumentLoadingTask, PDFDocumentProxy, PDFPageProxy, PDFWorkerUtil, RenderTask */\n/* harmony import */ var _shared_util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(292);\n/* harmony import */ var _annotation_storage_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(792);\n/* harmony import */ var _display_utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(419);\n/* harmony import */ var _font_loader_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(10);\n/* harmony import */ var display_node_utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(573);\n/* harmony import */ var _canvas_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(923);\n/* harmony import */ var _text_layer_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(814);\n/* harmony import */ var _worker_options_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(164);\n/* harmony import */ var _shared_message_handler_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(178);\n/* harmony import */ var _metadata_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(62);\n/* harmony import */ var _optional_content_config_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(626);\n/* harmony import */ var _transport_stream_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(585);\n/* harmony import */ var display_fetch_stream__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(94);\n/* harmony import */ var display_network__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(457);\n/* harmony import */ var display_node_stream__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(786);\n/* harmony import */ var _xfa_text_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(50);\nvar __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([display_node_utils__WEBPACK_IMPORTED_MODULE_4__, display_node_stream__WEBPACK_IMPORTED_MODULE_13__]);\n([display_node_utils__WEBPACK_IMPORTED_MODULE_4__, display_node_stream__WEBPACK_IMPORTED_MODULE_13__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst DEFAULT_RANGE_CHUNK_SIZE = 65536;\nconst RENDERING_CANCELLED_TIMEOUT = 100;\nconst DELAYED_CLEANUP_TIMEOUT = 5000;\nconst DefaultCanvasFactory = _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.isNodeJS ? display_node_utils__WEBPACK_IMPORTED_MODULE_4__.NodeCanvasFactory : _display_utils_js__WEBPACK_IMPORTED_MODULE_2__.DOMCanvasFactory;\nconst DefaultCMapReaderFactory = _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.isNodeJS ? display_node_utils__WEBPACK_IMPORTED_MODULE_4__.NodeCMapReaderFactory : _display_utils_js__WEBPACK_IMPORTED_MODULE_2__.DOMCMapReaderFactory;\nconst DefaultFilterFactory = _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.isNodeJS ? display_node_utils__WEBPACK_IMPORTED_MODULE_4__.NodeFilterFactory : _display_utils_js__WEBPACK_IMPORTED_MODULE_2__.DOMFilterFactory;\nconst DefaultStandardFontDataFactory = _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.isNodeJS ? display_node_utils__WEBPACK_IMPORTED_MODULE_4__.NodeStandardFontDataFactory : _display_utils_js__WEBPACK_IMPORTED_MODULE_2__.DOMStandardFontDataFactory;\nfunction getDocument(src) {\n  if (typeof src === \"string\" || src instanceof URL) {\n    src = {\n      url: src\n    };\n  } else if (src instanceof ArrayBuffer || ArrayBuffer.isView(src)) {\n    src = {\n      data: src\n    };\n  }\n  if (typeof src !== \"object\") {\n    throw new Error(\"Invalid parameter in getDocument, need parameter object.\");\n  }\n  if (!src.url && !src.data && !src.range) {\n    throw new Error(\"Invalid parameter object: need either .data, .range or .url\");\n  }\n  const task = new PDFDocumentLoadingTask();\n  const {\n    docId\n  } = task;\n  const url = src.url ? getUrlProp(src.url) : null;\n  const data = src.data ? getDataProp(src.data) : null;\n  const httpHeaders = src.httpHeaders || null;\n  const withCredentials = src.withCredentials === true;\n  const password = src.password ?? null;\n  const rangeTransport = src.range instanceof PDFDataRangeTransport ? src.range : null;\n  const rangeChunkSize = Number.isInteger(src.rangeChunkSize) && src.rangeChunkSize > 0 ? src.rangeChunkSize : DEFAULT_RANGE_CHUNK_SIZE;\n  let worker = src.worker instanceof PDFWorker ? src.worker : null;\n  const verbosity = src.verbosity;\n  const docBaseUrl = typeof src.docBaseUrl === \"string\" && !(0,_display_utils_js__WEBPACK_IMPORTED_MODULE_2__.isDataScheme)(src.docBaseUrl) ? src.docBaseUrl : null;\n  const cMapUrl = typeof src.cMapUrl === \"string\" ? src.cMapUrl : null;\n  const cMapPacked = src.cMapPacked !== false;\n  const CMapReaderFactory = src.CMapReaderFactory || DefaultCMapReaderFactory;\n  const standardFontDataUrl = typeof src.standardFontDataUrl === \"string\" ? src.standardFontDataUrl : null;\n  const StandardFontDataFactory = src.StandardFontDataFactory || DefaultStandardFontDataFactory;\n  const ignoreErrors = src.stopAtErrors !== true;\n  const maxImageSize = Number.isInteger(src.maxImageSize) && src.maxImageSize > -1 ? src.maxImageSize : -1;\n  const isEvalSupported = src.isEvalSupported !== false;\n  const isOffscreenCanvasSupported = typeof src.isOffscreenCanvasSupported === \"boolean\" ? src.isOffscreenCanvasSupported : !_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.isNodeJS;\n  const canvasMaxAreaInBytes = Number.isInteger(src.canvasMaxAreaInBytes) ? src.canvasMaxAreaInBytes : -1;\n  const disableFontFace = typeof src.disableFontFace === \"boolean\" ? src.disableFontFace : _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.isNodeJS;\n  const fontExtraProperties = src.fontExtraProperties === true;\n  const enableXfa = src.enableXfa === true;\n  const ownerDocument = src.ownerDocument || globalThis.document;\n  const disableRange = src.disableRange === true;\n  const disableStream = src.disableStream === true;\n  const disableAutoFetch = src.disableAutoFetch === true;\n  const pdfBug = src.pdfBug === true;\n  const length = rangeTransport ? rangeTransport.length : src.length ?? NaN;\n  const useSystemFonts = typeof src.useSystemFonts === \"boolean\" ? src.useSystemFonts : !_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.isNodeJS && !disableFontFace;\n  const useWorkerFetch = typeof src.useWorkerFetch === \"boolean\" ? src.useWorkerFetch : CMapReaderFactory === _display_utils_js__WEBPACK_IMPORTED_MODULE_2__.DOMCMapReaderFactory && StandardFontDataFactory === _display_utils_js__WEBPACK_IMPORTED_MODULE_2__.DOMStandardFontDataFactory && cMapUrl && standardFontDataUrl && (0,_display_utils_js__WEBPACK_IMPORTED_MODULE_2__.isValidFetchUrl)(cMapUrl, document.baseURI) && (0,_display_utils_js__WEBPACK_IMPORTED_MODULE_2__.isValidFetchUrl)(standardFontDataUrl, document.baseURI);\n  const canvasFactory = src.canvasFactory || new DefaultCanvasFactory({\n    ownerDocument\n  });\n  const filterFactory = src.filterFactory || new DefaultFilterFactory({\n    docId,\n    ownerDocument\n  });\n  const styleElement = null;\n  (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.setVerbosityLevel)(verbosity);\n  const transportFactory = {\n    canvasFactory,\n    filterFactory\n  };\n  if (!useWorkerFetch) {\n    transportFactory.cMapReaderFactory = new CMapReaderFactory({\n      baseUrl: cMapUrl,\n      isCompressed: cMapPacked\n    });\n    transportFactory.standardFontDataFactory = new StandardFontDataFactory({\n      baseUrl: standardFontDataUrl\n    });\n  }\n  if (!worker) {\n    const workerParams = {\n      verbosity,\n      port: _worker_options_js__WEBPACK_IMPORTED_MODULE_14__.GlobalWorkerOptions.workerPort\n    };\n    worker = workerParams.port ? PDFWorker.fromPort(workerParams) : new PDFWorker(workerParams);\n    task._worker = worker;\n  }\n  const fetchDocParams = {\n    docId,\n    apiVersion: \"4.1.0\",\n    data,\n    password,\n    disableAutoFetch,\n    rangeChunkSize,\n    length,\n    docBaseUrl,\n    enableXfa,\n    evaluatorOptions: {\n      maxImageSize,\n      disableFontFace,\n      ignoreErrors,\n      isEvalSupported,\n      isOffscreenCanvasSupported,\n      canvasMaxAreaInBytes,\n      fontExtraProperties,\n      useSystemFonts,\n      cMapUrl: useWorkerFetch ? cMapUrl : null,\n      standardFontDataUrl: useWorkerFetch ? standardFontDataUrl : null\n    }\n  };\n  const transportParams = {\n    ignoreErrors,\n    isEvalSupported,\n    disableFontFace,\n    fontExtraProperties,\n    enableXfa,\n    ownerDocument,\n    disableAutoFetch,\n    pdfBug,\n    styleElement\n  };\n  worker.promise.then(function () {\n    if (task.destroyed) {\n      throw new Error(\"Loading aborted\");\n    }\n    const workerIdPromise = _fetchDocument(worker, fetchDocParams);\n    const networkStreamPromise = new Promise(function (resolve) {\n      let networkStream;\n      if (rangeTransport) {\n        networkStream = new _transport_stream_js__WEBPACK_IMPORTED_MODULE_10__.PDFDataTransportStream(rangeTransport, {\n          disableRange,\n          disableStream\n        });\n      } else if (!data) {\n        const createPDFNetworkStream = params => {\n          if (_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.isNodeJS) {\n            return new display_node_stream__WEBPACK_IMPORTED_MODULE_13__.PDFNodeStream(params);\n          }\n          return (0,_display_utils_js__WEBPACK_IMPORTED_MODULE_2__.isValidFetchUrl)(params.url) ? new display_fetch_stream__WEBPACK_IMPORTED_MODULE_11__.PDFFetchStream(params) : new display_network__WEBPACK_IMPORTED_MODULE_12__.PDFNetworkStream(params);\n        };\n        networkStream = createPDFNetworkStream({\n          url,\n          length,\n          httpHeaders,\n          withCredentials,\n          rangeChunkSize,\n          disableRange,\n          disableStream\n        });\n      }\n      resolve(networkStream);\n    });\n    return Promise.all([workerIdPromise, networkStreamPromise]).then(function ([workerId, networkStream]) {\n      if (task.destroyed) {\n        throw new Error(\"Loading aborted\");\n      }\n      const messageHandler = new _shared_message_handler_js__WEBPACK_IMPORTED_MODULE_7__.MessageHandler(docId, workerId, worker.port);\n      const transport = new WorkerTransport(messageHandler, task, networkStream, transportParams, transportFactory);\n      task._transport = transport;\n      messageHandler.send(\"Ready\", null);\n    });\n  }).catch(task._capability.reject);\n  return task;\n}\nasync function _fetchDocument(worker, source) {\n  if (worker.destroyed) {\n    throw new Error(\"Worker was destroyed\");\n  }\n  const workerId = await worker.messageHandler.sendWithPromise(\"GetDocRequest\", source, source.data ? [source.data.buffer] : null);\n  if (worker.destroyed) {\n    throw new Error(\"Worker was destroyed\");\n  }\n  return workerId;\n}\nfunction getUrlProp(val) {\n  if (val instanceof URL) {\n    return val.href;\n  }\n  try {\n    return new URL(val, window.location).href;\n  } catch {\n    if (_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.isNodeJS && typeof val === \"string\") {\n      return val;\n    }\n  }\n  throw new Error(\"Invalid PDF url data: \" + \"either string or URL-object is expected in the url property.\");\n}\nfunction getDataProp(val) {\n  if (_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.isNodeJS && typeof Buffer !== \"undefined\" && val instanceof Buffer) {\n    throw new Error(\"Please provide binary data as `Uint8Array`, rather than `Buffer`.\");\n  }\n  if (val instanceof Uint8Array && val.byteLength === val.buffer.byteLength) {\n    return val;\n  }\n  if (typeof val === \"string\") {\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.stringToBytes)(val);\n  }\n  if (val instanceof ArrayBuffer || ArrayBuffer.isView(val) || typeof val === \"object\" && !isNaN(val?.length)) {\n    return new Uint8Array(val);\n  }\n  throw new Error(\"Invalid PDF binary data: either TypedArray, \" + \"string, or array-like object is expected in the data property.\");\n}\nclass PDFDocumentLoadingTask {\n  static #docId = 0;\n  constructor() {\n    this._capability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n    this._transport = null;\n    this._worker = null;\n    this.docId = `d${PDFDocumentLoadingTask.#docId++}`;\n    this.destroyed = false;\n    this.onPassword = null;\n    this.onProgress = null;\n  }\n  get promise() {\n    return this._capability.promise;\n  }\n  async destroy() {\n    this.destroyed = true;\n    try {\n      if (this._worker?.port) {\n        this._worker._pendingDestroy = true;\n      }\n      await this._transport?.destroy();\n    } catch (ex) {\n      if (this._worker?.port) {\n        delete this._worker._pendingDestroy;\n      }\n      throw ex;\n    }\n    this._transport = null;\n    if (this._worker) {\n      this._worker.destroy();\n      this._worker = null;\n    }\n  }\n}\nclass PDFDataRangeTransport {\n  constructor(length, initialData, progressiveDone = false, contentDispositionFilename = null) {\n    this.length = length;\n    this.initialData = initialData;\n    this.progressiveDone = progressiveDone;\n    this.contentDispositionFilename = contentDispositionFilename;\n    this._rangeListeners = [];\n    this._progressListeners = [];\n    this._progressiveReadListeners = [];\n    this._progressiveDoneListeners = [];\n    this._readyCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n  }\n  addRangeListener(listener) {\n    this._rangeListeners.push(listener);\n  }\n  addProgressListener(listener) {\n    this._progressListeners.push(listener);\n  }\n  addProgressiveReadListener(listener) {\n    this._progressiveReadListeners.push(listener);\n  }\n  addProgressiveDoneListener(listener) {\n    this._progressiveDoneListeners.push(listener);\n  }\n  onDataRange(begin, chunk) {\n    for (const listener of this._rangeListeners) {\n      listener(begin, chunk);\n    }\n  }\n  onDataProgress(loaded, total) {\n    this._readyCapability.promise.then(() => {\n      for (const listener of this._progressListeners) {\n        listener(loaded, total);\n      }\n    });\n  }\n  onDataProgressiveRead(chunk) {\n    this._readyCapability.promise.then(() => {\n      for (const listener of this._progressiveReadListeners) {\n        listener(chunk);\n      }\n    });\n  }\n  onDataProgressiveDone() {\n    this._readyCapability.promise.then(() => {\n      for (const listener of this._progressiveDoneListeners) {\n        listener();\n      }\n    });\n  }\n  transportReady() {\n    this._readyCapability.resolve();\n  }\n  requestDataRange(begin, end) {\n    (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.unreachable)(\"Abstract method PDFDataRangeTransport.requestDataRange\");\n  }\n  abort() {}\n}\nclass PDFDocumentProxy {\n  constructor(pdfInfo, transport) {\n    this._pdfInfo = pdfInfo;\n    this._transport = transport;\n  }\n  get annotationStorage() {\n    return this._transport.annotationStorage;\n  }\n  get filterFactory() {\n    return this._transport.filterFactory;\n  }\n  get numPages() {\n    return this._pdfInfo.numPages;\n  }\n  get fingerprints() {\n    return this._pdfInfo.fingerprints;\n  }\n  get isPureXfa() {\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, \"isPureXfa\", !!this._transport._htmlForXfa);\n  }\n  get allXfaHtml() {\n    return this._transport._htmlForXfa;\n  }\n  getPage(pageNumber) {\n    return this._transport.getPage(pageNumber);\n  }\n  getPageIndex(ref) {\n    return this._transport.getPageIndex(ref);\n  }\n  getDestinations() {\n    return this._transport.getDestinations();\n  }\n  getDestination(id) {\n    return this._transport.getDestination(id);\n  }\n  getPageLabels() {\n    return this._transport.getPageLabels();\n  }\n  getPageLayout() {\n    return this._transport.getPageLayout();\n  }\n  getPageMode() {\n    return this._transport.getPageMode();\n  }\n  getViewerPreferences() {\n    return this._transport.getViewerPreferences();\n  }\n  getOpenAction() {\n    return this._transport.getOpenAction();\n  }\n  getAttachments() {\n    return this._transport.getAttachments();\n  }\n  getJSActions() {\n    return this._transport.getDocJSActions();\n  }\n  getOutline() {\n    return this._transport.getOutline();\n  }\n  getOptionalContentConfig({\n    intent = \"display\"\n  } = {}) {\n    const {\n      renderingIntent\n    } = this._transport.getRenderingIntent(intent);\n    return this._transport.getOptionalContentConfig(renderingIntent);\n  }\n  getPermissions() {\n    return this._transport.getPermissions();\n  }\n  getMetadata() {\n    return this._transport.getMetadata();\n  }\n  getMarkInfo() {\n    return this._transport.getMarkInfo();\n  }\n  getData() {\n    return this._transport.getData();\n  }\n  saveDocument() {\n    return this._transport.saveDocument();\n  }\n  getDownloadInfo() {\n    return this._transport.downloadInfoCapability.promise;\n  }\n  cleanup(keepLoadedFonts = false) {\n    return this._transport.startCleanup(keepLoadedFonts || this.isPureXfa);\n  }\n  destroy() {\n    return this.loadingTask.destroy();\n  }\n  get loadingParams() {\n    return this._transport.loadingParams;\n  }\n  get loadingTask() {\n    return this._transport.loadingTask;\n  }\n  getFieldObjects() {\n    return this._transport.getFieldObjects();\n  }\n  hasJSActions() {\n    return this._transport.hasJSActions();\n  }\n  getCalculationOrderIds() {\n    return this._transport.getCalculationOrderIds();\n  }\n}\nclass PDFPageProxy {\n  #delayedCleanupTimeout = null;\n  #pendingCleanup = false;\n  constructor(pageIndex, pageInfo, transport, pdfBug = false) {\n    this._pageIndex = pageIndex;\n    this._pageInfo = pageInfo;\n    this._transport = transport;\n    this._stats = pdfBug ? new _display_utils_js__WEBPACK_IMPORTED_MODULE_2__.StatTimer() : null;\n    this._pdfBug = pdfBug;\n    this.commonObjs = transport.commonObjs;\n    this.objs = new PDFObjects();\n    this._maybeCleanupAfterRender = false;\n    this._intentStates = new Map();\n    this.destroyed = false;\n  }\n  get pageNumber() {\n    return this._pageIndex + 1;\n  }\n  get rotate() {\n    return this._pageInfo.rotate;\n  }\n  get ref() {\n    return this._pageInfo.ref;\n  }\n  get userUnit() {\n    return this._pageInfo.userUnit;\n  }\n  get view() {\n    return this._pageInfo.view;\n  }\n  getViewport({\n    scale,\n    rotation = this.rotate,\n    offsetX = 0,\n    offsetY = 0,\n    dontFlip = false\n  } = {}) {\n    return new _display_utils_js__WEBPACK_IMPORTED_MODULE_2__.PageViewport({\n      viewBox: this.view,\n      scale,\n      rotation,\n      offsetX,\n      offsetY,\n      dontFlip\n    });\n  }\n  getAnnotations({\n    intent = \"display\"\n  } = {}) {\n    const {\n      renderingIntent\n    } = this._transport.getRenderingIntent(intent);\n    return this._transport.getAnnotations(this._pageIndex, renderingIntent);\n  }\n  getJSActions() {\n    return this._transport.getPageJSActions(this._pageIndex);\n  }\n  get filterFactory() {\n    return this._transport.filterFactory;\n  }\n  get isPureXfa() {\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, \"isPureXfa\", !!this._transport._htmlForXfa);\n  }\n  async getXfa() {\n    return this._transport._htmlForXfa?.children[this._pageIndex] || null;\n  }\n  render({\n    canvasContext,\n    viewport,\n    intent = \"display\",\n    annotationMode = _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE,\n    transform = null,\n    background = null,\n    optionalContentConfigPromise = null,\n    annotationCanvasMap = null,\n    pageColors = null,\n    printAnnotationStorage = null\n  }) {\n    this._stats?.time(\"Overall\");\n    const intentArgs = this._transport.getRenderingIntent(intent, annotationMode, printAnnotationStorage);\n    const {\n      renderingIntent,\n      cacheKey\n    } = intentArgs;\n    this.#pendingCleanup = false;\n    this.#abortDelayedCleanup();\n    optionalContentConfigPromise ||= this._transport.getOptionalContentConfig(renderingIntent);\n    let intentState = this._intentStates.get(cacheKey);\n    if (!intentState) {\n      intentState = Object.create(null);\n      this._intentStates.set(cacheKey, intentState);\n    }\n    if (intentState.streamReaderCancelTimeout) {\n      clearTimeout(intentState.streamReaderCancelTimeout);\n      intentState.streamReaderCancelTimeout = null;\n    }\n    const intentPrint = !!(renderingIntent & _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.RenderingIntentFlag.PRINT);\n    if (!intentState.displayReadyCapability) {\n      intentState.displayReadyCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n      intentState.operatorList = {\n        fnArray: [],\n        argsArray: [],\n        lastChunk: false,\n        separateAnnots: null\n      };\n      this._stats?.time(\"Page Request\");\n      this._pumpOperatorList(intentArgs);\n    }\n    const complete = error => {\n      intentState.renderTasks.delete(internalRenderTask);\n      if (this._maybeCleanupAfterRender || intentPrint) {\n        this.#pendingCleanup = true;\n      }\n      this.#tryCleanup(!intentPrint);\n      if (error) {\n        internalRenderTask.capability.reject(error);\n        this._abortOperatorList({\n          intentState,\n          reason: error instanceof Error ? error : new Error(error)\n        });\n      } else {\n        internalRenderTask.capability.resolve();\n      }\n      this._stats?.timeEnd(\"Rendering\");\n      this._stats?.timeEnd(\"Overall\");\n    };\n    const internalRenderTask = new InternalRenderTask({\n      callback: complete,\n      params: {\n        canvasContext,\n        viewport,\n        transform,\n        background\n      },\n      objs: this.objs,\n      commonObjs: this.commonObjs,\n      annotationCanvasMap,\n      operatorList: intentState.operatorList,\n      pageIndex: this._pageIndex,\n      canvasFactory: this._transport.canvasFactory,\n      filterFactory: this._transport.filterFactory,\n      useRequestAnimationFrame: !intentPrint,\n      pdfBug: this._pdfBug,\n      pageColors\n    });\n    (intentState.renderTasks ||= new Set()).add(internalRenderTask);\n    const renderTask = internalRenderTask.task;\n    Promise.all([intentState.displayReadyCapability.promise, optionalContentConfigPromise]).then(([transparency, optionalContentConfig]) => {\n      if (this.destroyed) {\n        complete();\n        return;\n      }\n      this._stats?.time(\"Rendering\");\n      if (!(optionalContentConfig.renderingIntent & renderingIntent)) {\n        throw new Error(\"Must use the same `intent`-argument when calling the `PDFPageProxy.render` \" + \"and `PDFDocumentProxy.getOptionalContentConfig` methods.\");\n      }\n      internalRenderTask.initializeGraphics({\n        transparency,\n        optionalContentConfig\n      });\n      internalRenderTask.operatorListChanged();\n    }).catch(complete);\n    return renderTask;\n  }\n  getOperatorList({\n    imageOutLlamaParse = \"./\",\n    disableImageExtraction = false,\n    intent = \"display\",\n    annotationMode = _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE,\n    printAnnotationStorage = null\n  } = {}) {\n    function operatorListChanged() {\n      if (intentState.operatorList.lastChunk) {\n        intentState.opListReadCapability.resolve(intentState.operatorList);\n        intentState.renderTasks.delete(opListTask);\n      }\n    }\n    const intentArgs = this._transport.getRenderingIntent(intent, annotationMode, printAnnotationStorage, true);\n    let intentState = this._intentStates.get(intentArgs.cacheKey);\n    if (!intentState) {\n      intentState = Object.create(null);\n      this._intentStates.set(intentArgs.cacheKey, intentState);\n    }\n    let opListTask;\n    if (!intentState.opListReadCapability) {\n      opListTask = Object.create(null);\n      opListTask.operatorListChanged = operatorListChanged;\n      intentState.opListReadCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n      (intentState.renderTasks ||= new Set()).add(opListTask);\n      intentState.operatorList = {\n        fnArray: [],\n        argsArray: [],\n        lastChunk: false,\n        separateAnnots: null\n      };\n      this._stats?.time(\"Page Request\");\n      intentArgs.imageOutLlamaParse = imageOutLlamaParse;\n      intentArgs.disableImageExtraction = disableImageExtraction;\n      this._pumpOperatorList(intentArgs);\n    }\n    return intentState.opListReadCapability.promise;\n  }\n  streamTextContent({\n    includeMarkedContent = false,\n    disableNormalization = false\n  } = {}) {\n    const TEXT_CONTENT_CHUNK_SIZE = 100;\n    return this._transport.messageHandler.sendWithStream(\"GetTextContent\", {\n      pageIndex: this._pageIndex,\n      includeMarkedContent: includeMarkedContent === true,\n      disableNormalization: disableNormalization === true\n    }, {\n      highWaterMark: TEXT_CONTENT_CHUNK_SIZE,\n      size(textContent) {\n        return textContent.items.length;\n      }\n    });\n  }\n  getTextContent(params = {}) {\n    if (this._transport._htmlForXfa) {\n      return this.getXfa().then(xfa => _xfa_text_js__WEBPACK_IMPORTED_MODULE_15__.XfaText.textContent(xfa));\n    }\n    const readableStream = this.streamTextContent(params);\n    return new Promise(function (resolve, reject) {\n      function pump() {\n        reader.read().then(function ({\n          value,\n          done\n        }) {\n          if (done) {\n            resolve(textContent);\n            return;\n          }\n          Object.assign(textContent.styles, value.styles);\n          for (const item of value.items) {\n            textContent.items.push(item);\n          }\n          pump();\n        }, reject);\n      }\n      const reader = readableStream.getReader();\n      const textContent = {\n        items: [],\n        styles: Object.create(null)\n      };\n      pump();\n    });\n  }\n  getStructTree() {\n    return this._transport.getStructTree(this._pageIndex);\n  }\n  _destroy() {\n    this.destroyed = true;\n    const waitOn = [];\n    for (const intentState of this._intentStates.values()) {\n      this._abortOperatorList({\n        intentState,\n        reason: new Error(\"Page was destroyed.\"),\n        force: true\n      });\n      if (intentState.opListReadCapability) {\n        continue;\n      }\n      for (const internalRenderTask of intentState.renderTasks) {\n        waitOn.push(internalRenderTask.completed);\n        internalRenderTask.cancel();\n      }\n    }\n    this.objs.clear();\n    this.#pendingCleanup = false;\n    this.#abortDelayedCleanup();\n    return Promise.all(waitOn);\n  }\n  cleanup(resetStats = false) {\n    this.#pendingCleanup = true;\n    const success = this.#tryCleanup(false);\n    if (resetStats && success) {\n      this._stats &&= new _display_utils_js__WEBPACK_IMPORTED_MODULE_2__.StatTimer();\n    }\n    return success;\n  }\n  #tryCleanup(delayed = false) {\n    this.#abortDelayedCleanup();\n    if (!this.#pendingCleanup || this.destroyed) {\n      return false;\n    }\n    if (delayed) {\n      this.#delayedCleanupTimeout = setTimeout(() => {\n        this.#delayedCleanupTimeout = null;\n        this.#tryCleanup(false);\n      }, DELAYED_CLEANUP_TIMEOUT);\n      return false;\n    }\n    for (const {\n      renderTasks,\n      operatorList\n    } of this._intentStates.values()) {\n      if (renderTasks.size > 0 || !operatorList.lastChunk) {\n        return false;\n      }\n    }\n    this._intentStates.clear();\n    this.objs.clear();\n    this.#pendingCleanup = false;\n    return true;\n  }\n  #abortDelayedCleanup() {\n    if (this.#delayedCleanupTimeout) {\n      clearTimeout(this.#delayedCleanupTimeout);\n      this.#delayedCleanupTimeout = null;\n    }\n  }\n  _startRenderPage(transparency, cacheKey) {\n    const intentState = this._intentStates.get(cacheKey);\n    if (!intentState) {\n      return;\n    }\n    this._stats?.timeEnd(\"Page Request\");\n    intentState.displayReadyCapability?.resolve(transparency);\n  }\n  _renderPageChunk(operatorListChunk, intentState) {\n    for (let i = 0, ii = operatorListChunk.length; i < ii; i++) {\n      intentState.operatorList.fnArray.push(operatorListChunk.fnArray[i]);\n      intentState.operatorList.argsArray.push(operatorListChunk.argsArray[i]);\n    }\n    intentState.operatorList.lastChunk = operatorListChunk.lastChunk;\n    intentState.operatorList.separateAnnots = operatorListChunk.separateAnnots;\n    for (const internalRenderTask of intentState.renderTasks) {\n      internalRenderTask.operatorListChanged();\n    }\n    if (operatorListChunk.lastChunk) {\n      this.#tryCleanup(true);\n    }\n  }\n  _pumpOperatorList({\n    imageOutLlamaParse = \"./\",\n    disableImageExtraction = false,\n    renderingIntent,\n    cacheKey,\n    annotationStorageSerializable\n  }) {\n    const {\n      map,\n      transfer\n    } = annotationStorageSerializable;\n    const readableStream = this._transport.messageHandler.sendWithStream(\"GetOperatorList\", {\n      pageIndex: this._pageIndex,\n      intent: renderingIntent,\n      cacheKey,\n      annotationStorage: map,\n      imageOutLlamaParse: imageOutLlamaParse,\n      disableImageExtraction: disableImageExtraction\n    }, transfer);\n    const reader = readableStream.getReader();\n    const intentState = this._intentStates.get(cacheKey);\n    intentState.streamReader = reader;\n    const pump = () => {\n      reader.read().then(({\n        value,\n        done\n      }) => {\n        if (done) {\n          intentState.streamReader = null;\n          return;\n        }\n        if (this._transport.destroyed) {\n          return;\n        }\n        this._renderPageChunk(value, intentState);\n        pump();\n      }, reason => {\n        intentState.streamReader = null;\n        if (this._transport.destroyed) {\n          return;\n        }\n        if (intentState.operatorList) {\n          intentState.operatorList.lastChunk = true;\n          for (const internalRenderTask of intentState.renderTasks) {\n            internalRenderTask.operatorListChanged();\n          }\n          this.#tryCleanup(true);\n        }\n        if (intentState.displayReadyCapability) {\n          intentState.displayReadyCapability.reject(reason);\n        } else if (intentState.opListReadCapability) {\n          intentState.opListReadCapability.reject(reason);\n        } else {\n          throw reason;\n        }\n      });\n    };\n    pump();\n  }\n  _abortOperatorList({\n    intentState,\n    reason,\n    force = false\n  }) {\n    if (!intentState.streamReader) {\n      return;\n    }\n    if (intentState.streamReaderCancelTimeout) {\n      clearTimeout(intentState.streamReaderCancelTimeout);\n      intentState.streamReaderCancelTimeout = null;\n    }\n    if (!force) {\n      if (intentState.renderTasks.size > 0) {\n        return;\n      }\n      if (reason instanceof _display_utils_js__WEBPACK_IMPORTED_MODULE_2__.RenderingCancelledException) {\n        let delay = RENDERING_CANCELLED_TIMEOUT;\n        if (reason.extraDelay > 0 && reason.extraDelay < 1000) {\n          delay += reason.extraDelay;\n        }\n        intentState.streamReaderCancelTimeout = setTimeout(() => {\n          intentState.streamReaderCancelTimeout = null;\n          this._abortOperatorList({\n            intentState,\n            reason,\n            force: true\n          });\n        }, delay);\n        return;\n      }\n    }\n    intentState.streamReader.cancel(new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AbortException(reason.message)).catch(() => {});\n    intentState.streamReader = null;\n    if (this._transport.destroyed) {\n      return;\n    }\n    for (const [curCacheKey, curIntentState] of this._intentStates) {\n      if (curIntentState === intentState) {\n        this._intentStates.delete(curCacheKey);\n        break;\n      }\n    }\n    this.cleanup();\n  }\n  get stats() {\n    return this._stats;\n  }\n}\nclass LoopbackPort {\n  #listeners = new Set();\n  #deferred = Promise.resolve();\n  postMessage(obj, transfer) {\n    let event;\n    if (typeof transfer === \"undefined\") {\n      event = {\n        data: obj\n      };\n    } else {\n      event = {\n        data: structuredClone(obj, transfer ? {\n          transfer\n        } : null)\n      };\n    }\n    this.#deferred.then(() => {\n      for (const listener of this.#listeners) {\n        listener.call(this, event);\n      }\n    });\n  }\n  addEventListener(name, listener) {\n    this.#listeners.add(listener);\n  }\n  removeEventListener(name, listener) {\n    this.#listeners.delete(listener);\n  }\n  terminate() {\n    this.#listeners.clear();\n  }\n}\nconst PDFWorkerUtil = {\n  isWorkerDisabled: false,\n  fakeWorkerId: 0\n};\n{\n  if (_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.isNodeJS) {\n    PDFWorkerUtil.isWorkerDisabled = true;\n    _worker_options_js__WEBPACK_IMPORTED_MODULE_14__.GlobalWorkerOptions.workerSrc ||= \"./pdf.worker.mjs\";\n  }\n  PDFWorkerUtil.isSameOrigin = function (baseUrl, otherUrl) {\n    let base;\n    try {\n      base = new URL(baseUrl);\n      if (!base.origin || base.origin === \"null\") {\n        return false;\n      }\n    } catch {\n      return false;\n    }\n    const other = new URL(otherUrl, base);\n    return base.origin === other.origin;\n  };\n  PDFWorkerUtil.createCDNWrapper = function (url) {\n    const wrapper = `await import(\"${url}\");`;\n    return URL.createObjectURL(new Blob([wrapper], {\n      type: \"text/javascript\"\n    }));\n  };\n}\nclass PDFWorker {\n  static #workerPorts;\n  constructor({\n    name = null,\n    port = null,\n    verbosity = (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.getVerbosityLevel)()\n  } = {}) {\n    this.name = name;\n    this.destroyed = false;\n    this.verbosity = verbosity;\n    this._readyCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n    this._port = null;\n    this._webWorker = null;\n    this._messageHandler = null;\n    if (port) {\n      if (PDFWorker.#workerPorts?.has(port)) {\n        throw new Error(\"Cannot use more than one PDFWorker per port.\");\n      }\n      (PDFWorker.#workerPorts ||= new WeakMap()).set(port, this);\n      this._initializeFromPort(port);\n      return;\n    }\n    this._initialize();\n  }\n  get promise() {\n    return this._readyCapability.promise;\n  }\n  get port() {\n    return this._port;\n  }\n  get messageHandler() {\n    return this._messageHandler;\n  }\n  _initializeFromPort(port) {\n    this._port = port;\n    this._messageHandler = new _shared_message_handler_js__WEBPACK_IMPORTED_MODULE_7__.MessageHandler(\"main\", \"worker\", port);\n    this._messageHandler.on(\"ready\", function () {});\n    this._readyCapability.resolve();\n    this._messageHandler.send(\"configure\", {\n      verbosity: this.verbosity\n    });\n  }\n  _initialize() {\n    if (!PDFWorkerUtil.isWorkerDisabled && !PDFWorker.#mainThreadWorkerMessageHandler) {\n      let {\n        workerSrc\n      } = PDFWorker;\n      try {\n        if (!PDFWorkerUtil.isSameOrigin(window.location.href, workerSrc)) {\n          workerSrc = PDFWorkerUtil.createCDNWrapper(new URL(workerSrc, window.location).href);\n        }\n        const worker = new Worker(workerSrc, {\n          type: \"module\"\n        });\n        const messageHandler = new _shared_message_handler_js__WEBPACK_IMPORTED_MODULE_7__.MessageHandler(\"main\", \"worker\", worker);\n        const terminateEarly = () => {\n          worker.removeEventListener(\"error\", onWorkerError);\n          messageHandler.destroy();\n          worker.terminate();\n          if (this.destroyed) {\n            this._readyCapability.reject(new Error(\"Worker was destroyed\"));\n          } else {\n            this._setupFakeWorker();\n          }\n        };\n        const onWorkerError = () => {\n          if (!this._webWorker) {\n            terminateEarly();\n          }\n        };\n        worker.addEventListener(\"error\", onWorkerError);\n        messageHandler.on(\"test\", data => {\n          worker.removeEventListener(\"error\", onWorkerError);\n          if (this.destroyed) {\n            terminateEarly();\n            return;\n          }\n          if (data) {\n            this._messageHandler = messageHandler;\n            this._port = worker;\n            this._webWorker = worker;\n            this._readyCapability.resolve();\n            messageHandler.send(\"configure\", {\n              verbosity: this.verbosity\n            });\n          } else {\n            this._setupFakeWorker();\n            messageHandler.destroy();\n            worker.terminate();\n          }\n        });\n        messageHandler.on(\"ready\", data => {\n          worker.removeEventListener(\"error\", onWorkerError);\n          if (this.destroyed) {\n            terminateEarly();\n            return;\n          }\n          try {\n            sendTest();\n          } catch {\n            this._setupFakeWorker();\n          }\n        });\n        const sendTest = () => {\n          const testObj = new Uint8Array();\n          messageHandler.send(\"test\", testObj, [testObj.buffer]);\n        };\n        sendTest();\n        return;\n      } catch {\n        (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.info)(\"The worker has been disabled.\");\n      }\n    }\n    this._setupFakeWorker();\n  }\n  _setupFakeWorker() {\n    if (!PDFWorkerUtil.isWorkerDisabled) {\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(\"Setting up fake worker.\");\n      PDFWorkerUtil.isWorkerDisabled = true;\n    }\n    PDFWorker._setupFakeWorkerGlobal.then(WorkerMessageHandler => {\n      if (this.destroyed) {\n        this._readyCapability.reject(new Error(\"Worker was destroyed\"));\n        return;\n      }\n      const port = new LoopbackPort();\n      this._port = port;\n      const id = `fake${PDFWorkerUtil.fakeWorkerId++}`;\n      const workerHandler = new _shared_message_handler_js__WEBPACK_IMPORTED_MODULE_7__.MessageHandler(id + \"_worker\", id, port);\n      WorkerMessageHandler.setup(workerHandler, port);\n      const messageHandler = new _shared_message_handler_js__WEBPACK_IMPORTED_MODULE_7__.MessageHandler(id, id + \"_worker\", port);\n      this._messageHandler = messageHandler;\n      this._readyCapability.resolve();\n      messageHandler.send(\"configure\", {\n        verbosity: this.verbosity\n      });\n    }).catch(reason => {\n      this._readyCapability.reject(new Error(`Setting up fake worker failed: \"${reason.message}\".`));\n    });\n  }\n  destroy() {\n    this.destroyed = true;\n    if (this._webWorker) {\n      this._webWorker.terminate();\n      this._webWorker = null;\n    }\n    PDFWorker.#workerPorts?.delete(this._port);\n    this._port = null;\n    if (this._messageHandler) {\n      this._messageHandler.destroy();\n      this._messageHandler = null;\n    }\n  }\n  static fromPort(params) {\n    if (!params?.port) {\n      throw new Error(\"PDFWorker.fromPort - invalid method signature.\");\n    }\n    const cachedPort = this.#workerPorts?.get(params.port);\n    if (cachedPort) {\n      if (cachedPort._pendingDestroy) {\n        throw new Error(\"PDFWorker.fromPort - the worker is being destroyed.\\n\" + \"Please remember to await `PDFDocumentLoadingTask.destroy()`-calls.\");\n      }\n      return cachedPort;\n    }\n    return new PDFWorker(params);\n  }\n  static get workerSrc() {\n    if (_worker_options_js__WEBPACK_IMPORTED_MODULE_14__.GlobalWorkerOptions.workerSrc) {\n      return _worker_options_js__WEBPACK_IMPORTED_MODULE_14__.GlobalWorkerOptions.workerSrc;\n    }\n    throw new Error('No \"GlobalWorkerOptions.workerSrc\" specified.');\n  }\n  static get #mainThreadWorkerMessageHandler() {\n    try {\n      return globalThis.pdfjsWorker?.WorkerMessageHandler || null;\n    } catch {\n      return null;\n    }\n  }\n  static get _setupFakeWorkerGlobal() {\n    const loader = async () => {\n      if (this.#mainThreadWorkerMessageHandler) {\n        return this.#mainThreadWorkerMessageHandler;\n      }\n      const worker = await import(/*webpackIgnore: true*/this.workerSrc);\n      return worker.WorkerMessageHandler;\n    };\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, \"_setupFakeWorkerGlobal\", loader());\n  }\n}\nclass WorkerTransport {\n  #methodPromises = new Map();\n  #pageCache = new Map();\n  #pagePromises = new Map();\n  #passwordCapability = null;\n  constructor(messageHandler, loadingTask, networkStream, params, factory) {\n    this.messageHandler = messageHandler;\n    this.loadingTask = loadingTask;\n    this.commonObjs = new PDFObjects();\n    this.fontLoader = new _font_loader_js__WEBPACK_IMPORTED_MODULE_3__.FontLoader({\n      ownerDocument: params.ownerDocument,\n      styleElement: params.styleElement\n    });\n    this._params = params;\n    this.canvasFactory = factory.canvasFactory;\n    this.filterFactory = factory.filterFactory;\n    this.cMapReaderFactory = factory.cMapReaderFactory;\n    this.standardFontDataFactory = factory.standardFontDataFactory;\n    this.destroyed = false;\n    this.destroyCapability = null;\n    this._networkStream = networkStream;\n    this._fullReader = null;\n    this._lastProgress = null;\n    this.downloadInfoCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n    this.setupMessageHandler();\n  }\n  #cacheSimpleMethod(name, data = null) {\n    const cachedPromise = this.#methodPromises.get(name);\n    if (cachedPromise) {\n      return cachedPromise;\n    }\n    const promise = this.messageHandler.sendWithPromise(name, data);\n    this.#methodPromises.set(name, promise);\n    return promise;\n  }\n  get annotationStorage() {\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, \"annotationStorage\", new _annotation_storage_js__WEBPACK_IMPORTED_MODULE_1__.AnnotationStorage());\n  }\n  getRenderingIntent(intent, annotationMode = _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE, printAnnotationStorage = null, isOpList = false) {\n    let renderingIntent = _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.RenderingIntentFlag.DISPLAY;\n    let annotationStorageSerializable = _annotation_storage_js__WEBPACK_IMPORTED_MODULE_1__.SerializableEmpty;\n    switch (intent) {\n      case \"any\":\n        renderingIntent = _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.RenderingIntentFlag.ANY;\n        break;\n      case \"display\":\n        break;\n      case \"print\":\n        renderingIntent = _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.RenderingIntentFlag.PRINT;\n        break;\n      default:\n        (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(`getRenderingIntent - invalid intent: ${intent}`);\n    }\n    switch (annotationMode) {\n      case _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.DISABLE:\n        renderingIntent += _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.RenderingIntentFlag.ANNOTATIONS_DISABLE;\n        break;\n      case _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE:\n        break;\n      case _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE_FORMS:\n        renderingIntent += _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.RenderingIntentFlag.ANNOTATIONS_FORMS;\n        break;\n      case _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE_STORAGE:\n        renderingIntent += _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.RenderingIntentFlag.ANNOTATIONS_STORAGE;\n        const annotationStorage = renderingIntent & _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.RenderingIntentFlag.PRINT && printAnnotationStorage instanceof _annotation_storage_js__WEBPACK_IMPORTED_MODULE_1__.PrintAnnotationStorage ? printAnnotationStorage : this.annotationStorage;\n        annotationStorageSerializable = annotationStorage.serializable;\n        break;\n      default:\n        (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(`getRenderingIntent - invalid annotationMode: ${annotationMode}`);\n    }\n    if (isOpList) {\n      renderingIntent += _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.RenderingIntentFlag.OPLIST;\n    }\n    return {\n      renderingIntent,\n      cacheKey: `${renderingIntent}_${annotationStorageSerializable.hash}`,\n      annotationStorageSerializable\n    };\n  }\n  destroy() {\n    if (this.destroyCapability) {\n      return this.destroyCapability.promise;\n    }\n    this.destroyed = true;\n    this.destroyCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n    this.#passwordCapability?.reject(new Error(\"Worker was destroyed during onPassword callback\"));\n    const waitOn = [];\n    for (const page of this.#pageCache.values()) {\n      waitOn.push(page._destroy());\n    }\n    this.#pageCache.clear();\n    this.#pagePromises.clear();\n    if (this.hasOwnProperty(\"annotationStorage\")) {\n      this.annotationStorage.resetModified();\n    }\n    const terminated = this.messageHandler.sendWithPromise(\"Terminate\", null);\n    waitOn.push(terminated);\n    Promise.all(waitOn).then(() => {\n      this.commonObjs.clear();\n      this.fontLoader.clear();\n      this.#methodPromises.clear();\n      this.filterFactory.destroy();\n      (0,_text_layer_js__WEBPACK_IMPORTED_MODULE_6__.cleanupTextLayer)();\n      this._networkStream?.cancelAllRequests(new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.AbortException(\"Worker was terminated.\"));\n      if (this.messageHandler) {\n        this.messageHandler.destroy();\n        this.messageHandler = null;\n      }\n      this.destroyCapability.resolve();\n    }, this.destroyCapability.reject);\n    return this.destroyCapability.promise;\n  }\n  setupMessageHandler() {\n    const {\n      messageHandler,\n      loadingTask\n    } = this;\n    messageHandler.on(\"GetReader\", (data, sink) => {\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.assert)(this._networkStream, \"GetReader - no `IPDFStream` instance available.\");\n      this._fullReader = this._networkStream.getFullReader();\n      this._fullReader.onProgress = evt => {\n        this._lastProgress = {\n          loaded: evt.loaded,\n          total: evt.total\n        };\n      };\n      sink.onPull = () => {\n        this._fullReader.read().then(function ({\n          value,\n          done\n        }) {\n          if (done) {\n            sink.close();\n            return;\n          }\n          (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.assert)(value instanceof ArrayBuffer, \"GetReader - expected an ArrayBuffer.\");\n          sink.enqueue(new Uint8Array(value), 1, [value]);\n        }).catch(reason => {\n          sink.error(reason);\n        });\n      };\n      sink.onCancel = reason => {\n        this._fullReader.cancel(reason);\n        sink.ready.catch(readyReason => {\n          if (this.destroyed) {\n            return;\n          }\n          throw readyReason;\n        });\n      };\n    });\n    messageHandler.on(\"ReaderHeadersReady\", data => {\n      const headersCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n      const fullReader = this._fullReader;\n      fullReader.headersReady.then(() => {\n        if (!fullReader.isStreamingSupported || !fullReader.isRangeSupported) {\n          if (this._lastProgress) {\n            loadingTask.onProgress?.(this._lastProgress);\n          }\n          fullReader.onProgress = evt => {\n            loadingTask.onProgress?.({\n              loaded: evt.loaded,\n              total: evt.total\n            });\n          };\n        }\n        headersCapability.resolve({\n          isStreamingSupported: fullReader.isStreamingSupported,\n          isRangeSupported: fullReader.isRangeSupported,\n          contentLength: fullReader.contentLength\n        });\n      }, headersCapability.reject);\n      return headersCapability.promise;\n    });\n    messageHandler.on(\"GetRangeReader\", (data, sink) => {\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.assert)(this._networkStream, \"GetRangeReader - no `IPDFStream` instance available.\");\n      const rangeReader = this._networkStream.getRangeReader(data.begin, data.end);\n      if (!rangeReader) {\n        sink.close();\n        return;\n      }\n      sink.onPull = () => {\n        rangeReader.read().then(function ({\n          value,\n          done\n        }) {\n          if (done) {\n            sink.close();\n            return;\n          }\n          (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.assert)(value instanceof ArrayBuffer, \"GetRangeReader - expected an ArrayBuffer.\");\n          sink.enqueue(new Uint8Array(value), 1, [value]);\n        }).catch(reason => {\n          sink.error(reason);\n        });\n      };\n      sink.onCancel = reason => {\n        rangeReader.cancel(reason);\n        sink.ready.catch(readyReason => {\n          if (this.destroyed) {\n            return;\n          }\n          throw readyReason;\n        });\n      };\n    });\n    messageHandler.on(\"GetDoc\", ({\n      pdfInfo\n    }) => {\n      this._numPages = pdfInfo.numPages;\n      this._htmlForXfa = pdfInfo.htmlForXfa;\n      delete pdfInfo.htmlForXfa;\n      loadingTask._capability.resolve(new PDFDocumentProxy(pdfInfo, this));\n    });\n    messageHandler.on(\"DocException\", function (ex) {\n      let reason;\n      switch (ex.name) {\n        case \"PasswordException\":\n          reason = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PasswordException(ex.message, ex.code);\n          break;\n        case \"InvalidPDFException\":\n          reason = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.InvalidPDFException(ex.message);\n          break;\n        case \"MissingPDFException\":\n          reason = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.MissingPDFException(ex.message);\n          break;\n        case \"UnexpectedResponseException\":\n          reason = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.UnexpectedResponseException(ex.message, ex.status);\n          break;\n        case \"UnknownErrorException\":\n          reason = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.UnknownErrorException(ex.message, ex.details);\n          break;\n        default:\n          (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.unreachable)(\"DocException - expected a valid Error.\");\n      }\n      loadingTask._capability.reject(reason);\n    });\n    messageHandler.on(\"PasswordRequest\", exception => {\n      this.#passwordCapability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n      if (loadingTask.onPassword) {\n        const updatePassword = password => {\n          if (password instanceof Error) {\n            this.#passwordCapability.reject(password);\n          } else {\n            this.#passwordCapability.resolve({\n              password\n            });\n          }\n        };\n        try {\n          loadingTask.onPassword(updatePassword, exception.code);\n        } catch (ex) {\n          this.#passwordCapability.reject(ex);\n        }\n      } else {\n        this.#passwordCapability.reject(new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PasswordException(exception.message, exception.code));\n      }\n      return this.#passwordCapability.promise;\n    });\n    messageHandler.on(\"DataLoaded\", data => {\n      loadingTask.onProgress?.({\n        loaded: data.length,\n        total: data.length\n      });\n      this.downloadInfoCapability.resolve(data);\n    });\n    messageHandler.on(\"StartRenderPage\", data => {\n      if (this.destroyed) {\n        return;\n      }\n      const page = this.#pageCache.get(data.pageIndex);\n      page._startRenderPage(data.transparency, data.cacheKey);\n    });\n    messageHandler.on(\"commonobj\", ([id, type, exportedData]) => {\n      if (this.destroyed) {\n        return null;\n      }\n      if (this.commonObjs.has(id)) {\n        return null;\n      }\n      switch (type) {\n        case \"Font\":\n          const params = this._params;\n          if (\"error\" in exportedData) {\n            const exportedError = exportedData.error;\n            (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(`Error during font loading: ${exportedError}`);\n            this.commonObjs.resolve(id, exportedError);\n            break;\n          }\n          const inspectFont = params.pdfBug && globalThis.FontInspector?.enabled ? (font, url) => globalThis.FontInspector.fontAdded(font, url) : null;\n          const font = new _font_loader_js__WEBPACK_IMPORTED_MODULE_3__.FontFaceObject(exportedData, {\n            isEvalSupported: params.isEvalSupported,\n            disableFontFace: params.disableFontFace,\n            ignoreErrors: params.ignoreErrors,\n            inspectFont\n          });\n          this.fontLoader.bind(font).catch(() => messageHandler.sendWithPromise(\"FontFallback\", {\n            id\n          })).finally(() => {\n            if (!params.fontExtraProperties && font.data) {\n              font.data = null;\n            }\n            this.commonObjs.resolve(id, font);\n          });\n          break;\n        case \"CopyLocalImage\":\n          const {\n            imageRef\n          } = exportedData;\n          (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.assert)(imageRef, \"The imageRef must be defined.\");\n          for (const pageProxy of this.#pageCache.values()) {\n            for (const [, data] of pageProxy.objs) {\n              if (data.ref !== imageRef) {\n                continue;\n              }\n              if (!data.dataLen) {\n                return null;\n              }\n              this.commonObjs.resolve(id, structuredClone(data));\n              return data.dataLen;\n            }\n          }\n          break;\n        case \"FontPath\":\n        case \"Image\":\n        case \"Pattern\":\n          this.commonObjs.resolve(id, exportedData);\n          break;\n        default:\n          throw new Error(`Got unknown common object type ${type}`);\n      }\n      return null;\n    });\n    messageHandler.on(\"obj\", ([id, pageIndex, type, imageData]) => {\n      if (this.destroyed) {\n        return;\n      }\n      const pageProxy = this.#pageCache.get(pageIndex);\n      if (pageProxy.objs.has(id)) {\n        return;\n      }\n      if (pageProxy._intentStates.size === 0) {\n        imageData?.bitmap?.close();\n        return;\n      }\n      switch (type) {\n        case \"Image\":\n          pageProxy.objs.resolve(id, imageData);\n          if (imageData?.dataLen > _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.MAX_IMAGE_SIZE_TO_CACHE) {\n            pageProxy._maybeCleanupAfterRender = true;\n          }\n          break;\n        case \"Pattern\":\n          pageProxy.objs.resolve(id, imageData);\n          break;\n        default:\n          throw new Error(`Got unknown object type ${type}`);\n      }\n    });\n    messageHandler.on(\"DocProgress\", data => {\n      if (this.destroyed) {\n        return;\n      }\n      loadingTask.onProgress?.({\n        loaded: data.loaded,\n        total: data.total\n      });\n    });\n    messageHandler.on(\"FetchBuiltInCMap\", data => {\n      if (this.destroyed) {\n        return Promise.reject(new Error(\"Worker was destroyed.\"));\n      }\n      if (!this.cMapReaderFactory) {\n        return Promise.reject(new Error(\"CMapReaderFactory not initialized, see the `useWorkerFetch` parameter.\"));\n      }\n      return this.cMapReaderFactory.fetch(data);\n    });\n    messageHandler.on(\"FetchStandardFontData\", data => {\n      if (this.destroyed) {\n        return Promise.reject(new Error(\"Worker was destroyed.\"));\n      }\n      if (!this.standardFontDataFactory) {\n        return Promise.reject(new Error(\"StandardFontDataFactory not initialized, see the `useWorkerFetch` parameter.\"));\n      }\n      return this.standardFontDataFactory.fetch(data);\n    });\n  }\n  getData() {\n    return this.messageHandler.sendWithPromise(\"GetData\", null);\n  }\n  saveDocument() {\n    if (this.annotationStorage.size <= 0) {\n      (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.warn)(\"saveDocument called while `annotationStorage` is empty, \" + \"please use the getData-method instead.\");\n    }\n    const {\n      map,\n      transfer\n    } = this.annotationStorage.serializable;\n    return this.messageHandler.sendWithPromise(\"SaveDocument\", {\n      isPureXfa: !!this._htmlForXfa,\n      numPages: this._numPages,\n      annotationStorage: map,\n      filename: this._fullReader?.filename ?? null\n    }, transfer).finally(() => {\n      this.annotationStorage.resetModified();\n    });\n  }\n  getPage(pageNumber) {\n    if (!Number.isInteger(pageNumber) || pageNumber <= 0 || pageNumber > this._numPages) {\n      return Promise.reject(new Error(\"Invalid page request.\"));\n    }\n    const pageIndex = pageNumber - 1,\n      cachedPromise = this.#pagePromises.get(pageIndex);\n    if (cachedPromise) {\n      return cachedPromise;\n    }\n    const promise = this.messageHandler.sendWithPromise(\"GetPage\", {\n      pageIndex\n    }).then(pageInfo => {\n      if (this.destroyed) {\n        throw new Error(\"Transport destroyed\");\n      }\n      const page = new PDFPageProxy(pageIndex, pageInfo, this, this._params.pdfBug);\n      this.#pageCache.set(pageIndex, page);\n      return page;\n    });\n    this.#pagePromises.set(pageIndex, promise);\n    return promise;\n  }\n  getPageIndex(ref) {\n    if (typeof ref !== \"object\" || ref === null || !Number.isInteger(ref.num) || ref.num < 0 || !Number.isInteger(ref.gen) || ref.gen < 0) {\n      return Promise.reject(new Error(\"Invalid pageIndex request.\"));\n    }\n    return this.messageHandler.sendWithPromise(\"GetPageIndex\", {\n      num: ref.num,\n      gen: ref.gen\n    });\n  }\n  getAnnotations(pageIndex, intent) {\n    return this.messageHandler.sendWithPromise(\"GetAnnotations\", {\n      pageIndex,\n      intent\n    });\n  }\n  getFieldObjects() {\n    return this.#cacheSimpleMethod(\"GetFieldObjects\");\n  }\n  hasJSActions() {\n    return this.#cacheSimpleMethod(\"HasJSActions\");\n  }\n  getCalculationOrderIds() {\n    return this.messageHandler.sendWithPromise(\"GetCalculationOrderIds\", null);\n  }\n  getDestinations() {\n    return this.messageHandler.sendWithPromise(\"GetDestinations\", null);\n  }\n  getDestination(id) {\n    if (typeof id !== \"string\") {\n      return Promise.reject(new Error(\"Invalid destination request.\"));\n    }\n    return this.messageHandler.sendWithPromise(\"GetDestination\", {\n      id\n    });\n  }\n  getPageLabels() {\n    return this.messageHandler.sendWithPromise(\"GetPageLabels\", null);\n  }\n  getPageLayout() {\n    return this.messageHandler.sendWithPromise(\"GetPageLayout\", null);\n  }\n  getPageMode() {\n    return this.messageHandler.sendWithPromise(\"GetPageMode\", null);\n  }\n  getViewerPreferences() {\n    return this.messageHandler.sendWithPromise(\"GetViewerPreferences\", null);\n  }\n  getOpenAction() {\n    return this.messageHandler.sendWithPromise(\"GetOpenAction\", null);\n  }\n  getAttachments() {\n    return this.messageHandler.sendWithPromise(\"GetAttachments\", null);\n  }\n  getDocJSActions() {\n    return this.#cacheSimpleMethod(\"GetDocJSActions\");\n  }\n  getPageJSActions(pageIndex) {\n    return this.messageHandler.sendWithPromise(\"GetPageJSActions\", {\n      pageIndex\n    });\n  }\n  getStructTree(pageIndex) {\n    return this.messageHandler.sendWithPromise(\"GetStructTree\", {\n      pageIndex\n    });\n  }\n  getOutline() {\n    return this.messageHandler.sendWithPromise(\"GetOutline\", null);\n  }\n  getOptionalContentConfig(renderingIntent) {\n    return this.#cacheSimpleMethod(\"GetOptionalContentConfig\").then(data => new _optional_content_config_js__WEBPACK_IMPORTED_MODULE_9__.OptionalContentConfig(data, renderingIntent));\n  }\n  getPermissions() {\n    return this.messageHandler.sendWithPromise(\"GetPermissions\", null);\n  }\n  getMetadata() {\n    const name = \"GetMetadata\",\n      cachedPromise = this.#methodPromises.get(name);\n    if (cachedPromise) {\n      return cachedPromise;\n    }\n    const promise = this.messageHandler.sendWithPromise(name, null).then(results => ({\n      info: results[0],\n      metadata: results[1] ? new _metadata_js__WEBPACK_IMPORTED_MODULE_8__.Metadata(results[1]) : null,\n      contentDispositionFilename: this._fullReader?.filename ?? null,\n      contentLength: this._fullReader?.contentLength ?? null\n    }));\n    this.#methodPromises.set(name, promise);\n    return promise;\n  }\n  getMarkInfo() {\n    return this.messageHandler.sendWithPromise(\"GetMarkInfo\", null);\n  }\n  async startCleanup(keepLoadedFonts = false) {\n    if (this.destroyed) {\n      return;\n    }\n    await this.messageHandler.sendWithPromise(\"Cleanup\", null);\n    for (const page of this.#pageCache.values()) {\n      const cleanupSuccessful = page.cleanup();\n      if (!cleanupSuccessful) {\n        throw new Error(`startCleanup: Page ${page.pageNumber} is currently rendering.`);\n      }\n    }\n    this.commonObjs.clear();\n    if (!keepLoadedFonts) {\n      this.fontLoader.clear();\n    }\n    this.#methodPromises.clear();\n    this.filterFactory.destroy(true);\n    (0,_text_layer_js__WEBPACK_IMPORTED_MODULE_6__.cleanupTextLayer)();\n  }\n  get loadingParams() {\n    const {\n      disableAutoFetch,\n      enableXfa\n    } = this._params;\n    return (0,_shared_util_js__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, \"loadingParams\", {\n      disableAutoFetch,\n      enableXfa\n    });\n  }\n}\nclass PDFObjects {\n  #objs = Object.create(null);\n  #ensureObj(objId) {\n    return this.#objs[objId] ||= {\n      capability: new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability(),\n      data: null\n    };\n  }\n  get(objId, callback = null) {\n    if (callback) {\n      const obj = this.#ensureObj(objId);\n      obj.capability.promise.then(() => callback(obj.data));\n      return null;\n    }\n    const obj = this.#objs[objId];\n    if (!obj?.capability.settled) {\n      throw new Error(`Requesting object that isn't resolved yet ${objId}.`);\n    }\n    return obj.data;\n  }\n  getAll() {\n    return this.#objs;\n  }\n  has(objId) {\n    const obj = this.#objs[objId];\n    return obj?.capability.settled ?? false;\n  }\n  resolve(objId, data = null) {\n    const obj = this.#ensureObj(objId);\n    obj.data = data;\n    obj.capability.resolve();\n  }\n  clear() {\n    for (const objId in this.#objs) {\n      const {\n        data\n      } = this.#objs[objId];\n      data?.bitmap?.close();\n    }\n    this.#objs = Object.create(null);\n  }\n  *[Symbol.iterator]() {\n    for (const objId in this.#objs) {\n      const {\n        capability,\n        data\n      } = this.#objs[objId];\n      if (!capability.settled) {\n        continue;\n      }\n      yield [objId, data];\n    }\n  }\n}\nclass RenderTask {\n  #internalRenderTask = null;\n  constructor(internalRenderTask) {\n    this.#internalRenderTask = internalRenderTask;\n    this.onContinue = null;\n  }\n  get promise() {\n    return this.#internalRenderTask.capability.promise;\n  }\n  cancel(extraDelay = 0) {\n    this.#internalRenderTask.cancel(null, extraDelay);\n  }\n  get separateAnnots() {\n    const {\n      separateAnnots\n    } = this.#internalRenderTask.operatorList;\n    if (!separateAnnots) {\n      return false;\n    }\n    const {\n      annotationCanvasMap\n    } = this.#internalRenderTask;\n    return separateAnnots.form || separateAnnots.canvas && annotationCanvasMap?.size > 0;\n  }\n}\nclass InternalRenderTask {\n  static #canvasInUse = new WeakSet();\n  constructor({\n    callback,\n    params,\n    objs,\n    commonObjs,\n    annotationCanvasMap,\n    operatorList,\n    pageIndex,\n    canvasFactory,\n    filterFactory,\n    useRequestAnimationFrame = false,\n    pdfBug = false,\n    pageColors = null\n  }) {\n    this.callback = callback;\n    this.params = params;\n    this.objs = objs;\n    this.commonObjs = commonObjs;\n    this.annotationCanvasMap = annotationCanvasMap;\n    this.operatorListIdx = null;\n    this.operatorList = operatorList;\n    this._pageIndex = pageIndex;\n    this.canvasFactory = canvasFactory;\n    this.filterFactory = filterFactory;\n    this._pdfBug = pdfBug;\n    this.pageColors = pageColors;\n    this.running = false;\n    this.graphicsReadyCallback = null;\n    this.graphicsReady = false;\n    this._useRequestAnimationFrame = useRequestAnimationFrame === true && typeof window !== \"undefined\";\n    this.cancelled = false;\n    this.capability = new _shared_util_js__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();\n    this.task = new RenderTask(this);\n    this._cancelBound = this.cancel.bind(this);\n    this._continueBound = this._continue.bind(this);\n    this._scheduleNextBound = this._scheduleNext.bind(this);\n    this._nextBound = this._next.bind(this);\n    this._canvas = params.canvasContext.canvas;\n  }\n  get completed() {\n    return this.capability.promise.catch(function () {});\n  }\n  initializeGraphics({\n    transparency = false,\n    optionalContentConfig\n  }) {\n    if (this.cancelled) {\n      return;\n    }\n    if (this._canvas) {\n      if (InternalRenderTask.#canvasInUse.has(this._canvas)) {\n        throw new Error(\"Cannot use the same canvas during multiple render() operations. \" + \"Use different canvas or ensure previous operations were \" + \"cancelled or completed.\");\n      }\n      InternalRenderTask.#canvasInUse.add(this._canvas);\n    }\n    if (this._pdfBug && globalThis.StepperManager?.enabled) {\n      this.stepper = globalThis.StepperManager.create(this._pageIndex);\n      this.stepper.init(this.operatorList);\n      this.stepper.nextBreakPoint = this.stepper.getNextBreakPoint();\n    }\n    const {\n      canvasContext,\n      viewport,\n      transform,\n      background\n    } = this.params;\n    this.gfx = new _canvas_js__WEBPACK_IMPORTED_MODULE_5__.CanvasGraphics(canvasContext, this.commonObjs, this.objs, this.canvasFactory, this.filterFactory, {\n      optionalContentConfig\n    }, this.annotationCanvasMap, this.pageColors);\n    this.gfx.beginDrawing({\n      transform,\n      viewport,\n      transparency,\n      background\n    });\n    this.operatorListIdx = 0;\n    this.graphicsReady = true;\n    this.graphicsReadyCallback?.();\n  }\n  cancel(error = null, extraDelay = 0) {\n    this.running = false;\n    this.cancelled = true;\n    this.gfx?.endDrawing();\n    InternalRenderTask.#canvasInUse.delete(this._canvas);\n    this.callback(error || new _display_utils_js__WEBPACK_IMPORTED_MODULE_2__.RenderingCancelledException(`Rendering cancelled, page ${this._pageIndex + 1}`, extraDelay));\n  }\n  operatorListChanged() {\n    if (!this.graphicsReady) {\n      this.graphicsReadyCallback ||= this._continueBound;\n      return;\n    }\n    this.stepper?.updateOperatorList(this.operatorList);\n    if (this.running) {\n      return;\n    }\n    this._continue();\n  }\n  _continue() {\n    this.running = true;\n    if (this.cancelled) {\n      return;\n    }\n    if (this.task.onContinue) {\n      this.task.onContinue(this._scheduleNextBound);\n    } else {\n      this._scheduleNext();\n    }\n  }\n  _scheduleNext() {\n    if (this._useRequestAnimationFrame) {\n      window.requestAnimationFrame(() => {\n        this._nextBound().catch(this._cancelBound);\n      });\n    } else {\n      Promise.resolve().then(this._nextBound).catch(this._cancelBound);\n    }\n  }\n  async _next() {\n    if (this.cancelled) {\n      return;\n    }\n    this.operatorListIdx = this.gfx.executeOperatorList(this.operatorList, this.operatorListIdx, this._continueBound, this.stepper);\n    if (this.operatorListIdx === this.operatorList.argsArray.length) {\n      this.running = false;\n      if (this.operatorList.lastChunk) {\n        this.gfx.endDrawing();\n        InternalRenderTask.#canvasInUse.delete(this._canvas);\n        this.callback();\n      }\n    }\n  }\n}\nconst version = \"4.1.0\";\nconst build = \"849f8548b1\";\n\n__webpack_async_result__();\n} catch(e) { __webpack_async_result__(e); } });\n\n/***/ }),\n\n/***/ 923:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n  CanvasGraphics: () => (/* binding */ CanvasGraphics)\n});\n\n// EXTERNAL MODULE: ./src/shared/util.js\nvar util = __webpack_require__(292);\n// EXTERNAL MODULE: ./src/display/display_utils.js\nvar display_utils = __webpack_require__(419);\n;// ./src/display/pattern_helper.js\n\n\nconst PathType = {\n  FILL: \"Fill\",\n  STROKE: \"Stroke\",\n  SHADING: \"Shading\"\n};\nfunction applyBoundingBox(ctx, bbox) {\n  if (!bbox) {\n    return;\n  }\n  const width = bbox[2] - bbox[0];\n  const height = bbox[3] - bbox[1];\n  const region = new Path2D();\n  region.rect(bbox[0], bbox[1], width, height);\n  ctx.clip(region);\n}\nclass BaseShadingPattern {\n  constructor() {\n    if (this.constructor === BaseShadingPattern) {\n      (0,util.unreachable)(\"Cannot initialize BaseShadingPattern.\");\n    }\n  }\n  getPattern() {\n    (0,util.unreachable)(\"Abstract method `getPattern` called.\");\n  }\n}\nclass RadialAxialShadingPattern extends BaseShadingPattern {\n  constructor(IR) {\n    super();\n    this._type = IR[1];\n    this._bbox = IR[2];\n    this._colorStops = IR[3];\n    this._p0 = IR[4];\n    this._p1 = IR[5];\n    this._r0 = IR[6];\n    this._r1 = IR[7];\n    this.matrix = null;\n  }\n  _createGradient(ctx) {\n    let grad;\n    if (this._type === \"axial\") {\n      grad = ctx.createLinearGradient(this._p0[0], this._p0[1], this._p1[0], this._p1[1]);\n    } else if (this._type === \"radial\") {\n      grad = ctx.createRadialGradient(this._p0[0], this._p0[1], this._r0, this._p1[0], this._p1[1], this._r1);\n    }\n    for (const colorStop of this._colorStops) {\n      grad.addColorStop(colorStop[0], colorStop[1]);\n    }\n    return grad;\n  }\n  getPattern(ctx, owner, inverse, pathType) {\n    let pattern;\n    if (pathType === PathType.STROKE || pathType === PathType.FILL) {\n      const ownerBBox = owner.current.getClippedPathBoundingBox(pathType, (0,display_utils.getCurrentTransform)(ctx)) || [0, 0, 0, 0];\n      const width = Math.ceil(ownerBBox[2] - ownerBBox[0]) || 1;\n      const height = Math.ceil(ownerBBox[3] - ownerBBox[1]) || 1;\n      const tmpCanvas = owner.cachedCanvases.getCanvas(\"pattern\", width, height, true);\n      const tmpCtx = tmpCanvas.context;\n      tmpCtx.clearRect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height);\n      tmpCtx.beginPath();\n      tmpCtx.rect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height);\n      tmpCtx.translate(-ownerBBox[0], -ownerBBox[1]);\n      inverse = util.Util.transform(inverse, [1, 0, 0, 1, ownerBBox[0], ownerBBox[1]]);\n      tmpCtx.transform(...owner.baseTransform);\n      if (this.matrix) {\n        tmpCtx.transform(...this.matrix);\n      }\n      applyBoundingBox(tmpCtx, this._bbox);\n      tmpCtx.fillStyle = this._createGradient(tmpCtx);\n      tmpCtx.fill();\n      pattern = ctx.createPattern(tmpCanvas.canvas, \"no-repeat\");\n      const domMatrix = new DOMMatrix(inverse);\n      pattern.setTransform(domMatrix);\n    } else {\n      applyBoundingBox(ctx, this._bbox);\n      pattern = this._createGradient(ctx);\n    }\n    return pattern;\n  }\n}\nfunction drawTriangle(data, context, p1, p2, p3, c1, c2, c3) {\n  const coords = context.coords,\n    colors = context.colors;\n  const bytes = data.data,\n    rowSize = data.width * 4;\n  let tmp;\n  if (coords[p1 + 1] > coords[p2 + 1]) {\n    tmp = p1;\n    p1 = p2;\n    p2 = tmp;\n    tmp = c1;\n    c1 = c2;\n    c2 = tmp;\n  }\n  if (coords[p2 + 1] > coords[p3 + 1]) {\n    tmp = p2;\n    p2 = p3;\n    p3 = tmp;\n    tmp = c2;\n    c2 = c3;\n    c3 = tmp;\n  }\n  if (coords[p1 + 1] > coords[p2 + 1]) {\n    tmp = p1;\n    p1 = p2;\n    p2 = tmp;\n    tmp = c1;\n    c1 = c2;\n    c2 = tmp;\n  }\n  const x1 = (coords[p1] + context.offsetX) * context.scaleX;\n  const y1 = (coords[p1 + 1] + context.offsetY) * context.scaleY;\n  const x2 = (coords[p2] + context.offsetX) * context.scaleX;\n  const y2 = (coords[p2 + 1] + context.offsetY) * context.scaleY;\n  const x3 = (coords[p3] + context.offsetX) * context.scaleX;\n  const y3 = (coords[p3 + 1] + context.offsetY) * context.scaleY;\n  if (y1 >= y3) {\n    return;\n  }\n  const c1r = colors[c1],\n    c1g = colors[c1 + 1],\n    c1b = colors[c1 + 2];\n  const c2r = colors[c2],\n    c2g = colors[c2 + 1],\n    c2b = colors[c2 + 2];\n  const c3r = colors[c3],\n    c3g = colors[c3 + 1],\n    c3b = colors[c3 + 2];\n  const minY = Math.round(y1),\n    maxY = Math.round(y3);\n  let xa, car, cag, cab;\n  let xb, cbr, cbg, cbb;\n  for (let y = minY; y <= maxY; y++) {\n    if (y < y2) {\n      const k = y < y1 ? 0 : (y1 - y) / (y1 - y2);\n      xa = x1 - (x1 - x2) * k;\n      car = c1r - (c1r - c2r) * k;\n      cag = c1g - (c1g - c2g) * k;\n      cab = c1b - (c1b - c2b) * k;\n    } else {\n      let k;\n      if (y > y3) {\n        k = 1;\n      } else if (y2 === y3) {\n        k = 0;\n      } else {\n        k = (y2 - y) / (y2 - y3);\n      }\n      xa = x2 - (x2 - x3) * k;\n      car = c2r - (c2r - c3r) * k;\n      cag = c2g - (c2g - c3g) * k;\n      cab = c2b - (c2b - c3b) * k;\n    }\n    let k;\n    if (y < y1) {\n      k = 0;\n    } else if (y > y3) {\n      k = 1;\n    } else {\n      k = (y1 - y) / (y1 - y3);\n    }\n    xb = x1 - (x1 - x3) * k;\n    cbr = c1r - (c1r - c3r) * k;\n    cbg = c1g - (c1g - c3g) * k;\n    cbb = c1b - (c1b - c3b) * k;\n    const x1_ = Math.round(Math.min(xa, xb));\n    const x2_ = Math.round(Math.max(xa, xb));\n    let j = rowSize * y + x1_ * 4;\n    for (let x = x1_; x <= x2_; x++) {\n      k = (xa - x) / (xa - xb);\n      if (k < 0) {\n        k = 0;\n      } else if (k > 1) {\n        k = 1;\n      }\n      bytes[j++] = car - (car - cbr) * k | 0;\n      bytes[j++] = cag - (cag - cbg) * k | 0;\n      bytes[j++] = cab - (cab - cbb) * k | 0;\n      bytes[j++] = 255;\n    }\n  }\n}\nfunction drawFigure(data, figure, context) {\n  const ps = figure.coords;\n  const cs = figure.colors;\n  let i, ii;\n  switch (figure.type) {\n    case \"lattice\":\n      const verticesPerRow = figure.verticesPerRow;\n      const rows = Math.floor(ps.length / verticesPerRow) - 1;\n      const cols = verticesPerRow - 1;\n      for (i = 0; i < rows; i++) {\n        let q = i * verticesPerRow;\n        for (let j = 0; j < cols; j++, q++) {\n          drawTriangle(data, context, ps[q], ps[q + 1], ps[q + verticesPerRow], cs[q], cs[q + 1], cs[q + verticesPerRow]);\n          drawTriangle(data, context, ps[q + verticesPerRow + 1], ps[q + 1], ps[q + verticesPerRow], cs[q + verticesPerRow + 1], cs[q + 1], cs[q + verticesPerRow]);\n        }\n      }\n      break;\n    case \"triangles\":\n      for (i = 0, ii = ps.length; i < ii; i += 3) {\n        drawTriangle(data, context, ps[i], ps[i + 1], ps[i + 2], cs[i], cs[i + 1], cs[i + 2]);\n      }\n      break;\n    default:\n      throw new Error(\"illegal figure\");\n  }\n}\nclass MeshShadingPattern extends BaseShadingPattern {\n  constructor(IR) {\n    super();\n    this._coords = IR[2];\n    this._colors = IR[3];\n    this._figures = IR[4];\n    this._bounds = IR[5];\n    this._bbox = IR[7];\n    this._background = IR[8];\n    this.matrix = null;\n  }\n  _createMeshCanvas(combinedScale, backgroundColor, cachedCanvases) {\n    const EXPECTED_SCALE = 1.1;\n    const MAX_PATTERN_SIZE = 3000;\n    const BORDER_SIZE = 2;\n    const offsetX = Math.floor(this._bounds[0]);\n    const offsetY = Math.floor(this._bounds[1]);\n    const boundsWidth = Math.ceil(this._bounds[2]) - offsetX;\n    const boundsHeight = Math.ceil(this._bounds[3]) - offsetY;\n    const width = Math.min(Math.ceil(Math.abs(boundsWidth * combinedScale[0] * EXPECTED_SCALE)), MAX_PATTERN_SIZE);\n    const height = Math.min(Math.ceil(Math.abs(boundsHeight * combinedScale[1] * EXPECTED_SCALE)), MAX_PATTERN_SIZE);\n    const scaleX = boundsWidth / width;\n    const scaleY = boundsHeight / height;\n    const context = {\n      coords: this._coords,\n      colors: this._colors,\n      offsetX: -offsetX,\n      offsetY: -offsetY,\n      scaleX: 1 / scaleX,\n      scaleY: 1 / scaleY\n    };\n    const paddedWidth = width + BORDER_SIZE * 2;\n    const paddedHeight = height + BORDER_SIZE * 2;\n    const tmpCanvas = cachedCanvases.getCanvas(\"mesh\", paddedWidth, paddedHeight, false);\n    const tmpCtx = tmpCanvas.context;\n    const data = tmpCtx.createImageData(width, height);\n    if (backgroundColor) {\n      const bytes = data.data;\n      for (let i = 0, ii = bytes.length; i < ii; i += 4) {\n        bytes[i] = backgroundColor[0];\n        bytes[i + 1] = backgroundColor[1];\n        bytes[i + 2] = backgroundColor[2];\n        bytes[i + 3] = 255;\n      }\n    }\n    for (const figure of this._figures) {\n      drawFigure(data, figure, context);\n    }\n    tmpCtx.putImageData(data, BORDER_SIZE, BORDER_SIZE);\n    const canvas = tmpCanvas.canvas;\n    return {\n      canvas,\n      offsetX: offsetX - BORDER_SIZE * scaleX,\n      offsetY: offsetY - BORDER_SIZE * scaleY,\n      scaleX,\n      scaleY\n    };\n  }\n  getPattern(ctx, owner, inverse, pathType) {\n    applyBoundingBox(ctx, this._bbox);\n    let scale;\n    if (pathType === PathType.SHADING) {\n      scale = util.Util.singularValueDecompose2dScale((0,display_utils.getCurrentTransform)(ctx));\n    } else {\n      scale = util.Util.singularValueDecompose2dScale(owner.baseTransform);\n      if (this.matrix) {\n        const matrixScale = util.Util.singularValueDecompose2dScale(this.matrix);\n        scale = [scale[0] * matrixScale[0], scale[1] * matrixScale[1]];\n      }\n    }\n    const temporaryPatternCanvas = this._createMeshCanvas(scale, pathType === PathType.SHADING ? null : this._background, owner.cachedCanvases);\n    if (pathType !== PathType.SHADING) {\n      ctx.setTransform(...owner.baseTransform);\n      if (this.matrix) {\n        ctx.transform(...this.matrix);\n      }\n    }\n    ctx.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY);\n    ctx.scale(temporaryPatternCanvas.scaleX, temporaryPatternCanvas.scaleY);\n    return ctx.createPattern(temporaryPatternCanvas.canvas, \"no-repeat\");\n  }\n}\nclass DummyShadingPattern extends BaseShadingPattern {\n  getPattern() {\n    return \"hotpink\";\n  }\n}\nfunction getShadingPattern(IR) {\n  switch (IR[0]) {\n    case \"RadialAxial\":\n      return new RadialAxialShadingPattern(IR);\n    case \"Mesh\":\n      return new MeshShadingPattern(IR);\n    case \"Dummy\":\n      return new DummyShadingPattern();\n  }\n  throw new Error(`Unknown IR type: ${IR[0]}`);\n}\nconst PaintType = {\n  COLORED: 1,\n  UNCOLORED: 2\n};\nclass TilingPattern {\n  static MAX_PATTERN_SIZE = 3000;\n  constructor(IR, color, ctx, canvasGraphicsFactory, baseTransform) {\n    this.operatorList = IR[2];\n    this.matrix = IR[3] || [1, 0, 0, 1, 0, 0];\n    this.bbox = IR[4];\n    this.xstep = IR[5];\n    this.ystep = IR[6];\n    this.paintType = IR[7];\n    this.tilingType = IR[8];\n    this.color = color;\n    this.ctx = ctx;\n    this.canvasGraphicsFactory = canvasGraphicsFactory;\n    this.baseTransform = baseTransform;\n  }\n  createPatternCanvas(owner) {\n    const operatorList = this.operatorList;\n    const bbox = this.bbox;\n    const xstep = this.xstep;\n    const ystep = this.ystep;\n    const paintType = this.paintType;\n    const tilingType = this.tilingType;\n    const color = this.color;\n    const canvasGraphicsFactory = this.canvasGraphicsFactory;\n    (0,util.info)(\"TilingType: \" + tilingType);\n    const x0 = bbox[0],\n      y0 = bbox[1],\n      x1 = bbox[2],\n      y1 = bbox[3];\n    const matrixScale = util.Util.singularValueDecompose2dScale(this.matrix);\n    const curMatrixScale = util.Util.singularValueDecompose2dScale(this.baseTransform);\n    const combinedScale = [matrixScale[0] * curMatrixScale[0], matrixScale[1] * curMatrixScale[1]];\n    const dimx = this.getSizeAndScale(xstep, this.ctx.canvas.width, combinedScale[0]);\n    const dimy = this.getSizeAndScale(ystep, this.ctx.canvas.height, combinedScale[1]);\n    const tmpCanvas = owner.cachedCanvases.getCanvas(\"pattern\", dimx.size, dimy.size, true);\n    const tmpCtx = tmpCanvas.context;\n    const graphics = canvasGraphicsFactory.createCanvasGraphics(tmpCtx);\n    graphics.groupLevel = owner.groupLevel;\n    this.setFillAndStrokeStyleToContext(graphics, paintType, color);\n    let adjustedX0 = x0;\n    let adjustedY0 = y0;\n    let adjustedX1 = x1;\n    let adjustedY1 = y1;\n    if (x0 < 0) {\n      adjustedX0 = 0;\n      adjustedX1 += Math.abs(x0);\n    }\n    if (y0 < 0) {\n      adjustedY0 = 0;\n      adjustedY1 += Math.abs(y0);\n    }\n    tmpCtx.translate(-(dimx.scale * adjustedX0), -(dimy.scale * adjustedY0));\n    graphics.transform(dimx.scale, 0, 0, dimy.scale, 0, 0);\n    tmpCtx.save();\n    this.clipBbox(graphics, adjustedX0, adjustedY0, adjustedX1, adjustedY1);\n    graphics.baseTransform = (0,display_utils.getCurrentTransform)(graphics.ctx);\n    graphics.executeOperatorList(operatorList);\n    graphics.endDrawing();\n    return {\n      canvas: tmpCanvas.canvas,\n      scaleX: dimx.scale,\n      scaleY: dimy.scale,\n      offsetX: adjustedX0,\n      offsetY: adjustedY0\n    };\n  }\n  getSizeAndScale(step, realOutputSize, scale) {\n    step = Math.abs(step);\n    const maxSize = Math.max(TilingPattern.MAX_PATTERN_SIZE, realOutputSize);\n    let size = Math.ceil(step * scale);\n    if (size >= maxSize) {\n      size = maxSize;\n    } else {\n      scale = size / step;\n    }\n    return {\n      scale,\n      size\n    };\n  }\n  clipBbox(graphics, x0, y0, x1, y1) {\n    const bboxWidth = x1 - x0;\n    const bboxHeight = y1 - y0;\n    graphics.ctx.rect(x0, y0, bboxWidth, bboxHeight);\n    graphics.current.updateRectMinMax((0,display_utils.getCurrentTransform)(graphics.ctx), [x0, y0, x1, y1]);\n    graphics.clip();\n    graphics.endPath();\n  }\n  setFillAndStrokeStyleToContext(graphics, paintType, color) {\n    const context = graphics.ctx,\n      current = graphics.current;\n    switch (paintType) {\n      case PaintType.COLORED:\n        const ctx = this.ctx;\n        context.fillStyle = ctx.fillStyle;\n        context.strokeStyle = ctx.strokeStyle;\n        current.fillColor = ctx.fillStyle;\n        current.strokeColor = ctx.strokeStyle;\n        break;\n      case PaintType.UNCOLORED:\n        const cssColor = util.Util.makeHexColor(color[0], color[1], color[2]);\n        context.fillStyle = cssColor;\n        context.strokeStyle = cssColor;\n        current.fillColor = cssColor;\n        current.strokeColor = cssColor;\n        break;\n      default:\n        throw new util.FormatError(`Unsupported paint type: ${paintType}`);\n    }\n  }\n  getPattern(ctx, owner, inverse, pathType) {\n    let matrix = inverse;\n    if (pathType !== PathType.SHADING) {\n      matrix = util.Util.transform(matrix, owner.baseTransform);\n      if (this.matrix) {\n        matrix = util.Util.transform(matrix, this.matrix);\n      }\n    }\n    const temporaryPatternCanvas = this.createPatternCanvas(owner);\n    let domMatrix = new DOMMatrix(matrix);\n    domMatrix = domMatrix.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY);\n    domMatrix = domMatrix.scale(1 / temporaryPatternCanvas.scaleX, 1 / temporaryPatternCanvas.scaleY);\n    const pattern = ctx.createPattern(temporaryPatternCanvas.canvas, \"repeat\");\n    pattern.setTransform(domMatrix);\n    return pattern;\n  }\n}\n\n;// ./src/shared/image_utils.js\n\nfunction convertToRGBA(params) {\n  switch (params.kind) {\n    case ImageKind.GRAYSCALE_1BPP:\n      return convertBlackAndWhiteToRGBA(params);\n    case ImageKind.RGB_24BPP:\n      return convertRGBToRGBA(params);\n  }\n  return null;\n}\nfunction convertBlackAndWhiteToRGBA({\n  src,\n  srcPos = 0,\n  dest,\n  width,\n  height,\n  nonBlackColor = 0xffffffff,\n  inverseDecode = false\n}) {\n  const black = util.FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff;\n  const [zeroMapping, oneMapping] = inverseDecode ? [nonBlackColor, black] : [black, nonBlackColor];\n  const widthInSource = width >> 3;\n  const widthRemainder = width & 7;\n  const srcLength = src.length;\n  dest = new Uint32Array(dest.buffer);\n  let destPos = 0;\n  for (let i = 0; i < height; i++) {\n    for (const max = srcPos + widthInSource; srcPos < max; srcPos++) {\n      const elem = srcPos < srcLength ? src[srcPos] : 255;\n      dest[destPos++] = elem & 0b10000000 ? oneMapping : zeroMapping;\n      dest[destPos++] = elem & 0b1000000 ? oneMapping : zeroMapping;\n      dest[destPos++] = elem & 0b100000 ? oneMapping : zeroMapping;\n      dest[destPos++] = elem & 0b10000 ? oneMapping : zeroMapping;\n      dest[destPos++] = elem & 0b1000 ? oneMapping : zeroMapping;\n      dest[destPos++] = elem & 0b100 ? oneMapping : zeroMapping;\n      dest[destPos++] = elem & 0b10 ? oneMapping : zeroMapping;\n      dest[destPos++] = elem & 0b1 ? oneMapping : zeroMapping;\n    }\n    if (widthRemainder === 0) {\n      continue;\n    }\n    const elem = srcPos < srcLength ? src[srcPos++] : 255;\n    for (let j = 0; j < widthRemainder; j++) {\n      dest[destPos++] = elem & 1 << 7 - j ? oneMapping : zeroMapping;\n    }\n  }\n  return {\n    srcPos,\n    destPos\n  };\n}\nfunction convertRGBToRGBA({\n  src,\n  srcPos = 0,\n  dest,\n  destPos = 0,\n  width,\n  height\n}) {\n  let i = 0;\n  const len32 = src.length >> 2;\n  const src32 = new Uint32Array(src.buffer, srcPos, len32);\n  if (FeatureTest.isLittleEndian) {\n    for (; i < len32 - 2; i += 3, destPos += 4) {\n      const s1 = src32[i];\n      const s2 = src32[i + 1];\n      const s3 = src32[i + 2];\n      dest[destPos] = s1 | 0xff000000;\n      dest[destPos + 1] = s1 >>> 24 | s2 << 8 | 0xff000000;\n      dest[destPos + 2] = s2 >>> 16 | s3 << 16 | 0xff000000;\n      dest[destPos + 3] = s3 >>> 8 | 0xff000000;\n    }\n    for (let j = i * 4, jj = src.length; j < jj; j += 3) {\n      dest[destPos++] = src[j] | src[j + 1] << 8 | src[j + 2] << 16 | 0xff000000;\n    }\n  } else {\n    for (; i < len32 - 2; i += 3, destPos += 4) {\n      const s1 = src32[i];\n      const s2 = src32[i + 1];\n      const s3 = src32[i + 2];\n      dest[destPos] = s1 | 0xff;\n      dest[destPos + 1] = s1 << 24 | s2 >>> 8 | 0xff;\n      dest[destPos + 2] = s2 << 16 | s3 >>> 16 | 0xff;\n      dest[destPos + 3] = s3 << 8 | 0xff;\n    }\n    for (let j = i * 4, jj = src.length; j < jj; j += 3) {\n      dest[destPos++] = src[j] << 24 | src[j + 1] << 16 | src[j + 2] << 8 | 0xff;\n    }\n  }\n  return {\n    srcPos,\n    destPos\n  };\n}\nfunction grayToRGBA(src, dest) {\n  if (FeatureTest.isLittleEndian) {\n    for (let i = 0, ii = src.length; i < ii; i++) {\n      dest[i] = src[i] * 0x10101 | 0xff000000;\n    }\n  } else {\n    for (let i = 0, ii = src.length; i < ii; i++) {\n      dest[i] = src[i] * 0x1010100 | 0x000000ff;\n    }\n  }\n}\n\n;// ./src/display/canvas.js\n\n\n\n\nconst MIN_FONT_SIZE = 16;\nconst MAX_FONT_SIZE = 100;\nconst MAX_GROUP_SIZE = 4096;\nconst EXECUTION_TIME = 15;\nconst EXECUTION_STEPS = 10;\nconst MAX_SIZE_TO_COMPILE = 1000;\nconst FULL_CHUNK_HEIGHT = 16;\nfunction mirrorContextOperations(ctx, destCtx) {\n  if (ctx._removeMirroring) {\n    throw new Error(\"Context is already forwarding operations.\");\n  }\n  ctx.__originalSave = ctx.save;\n  ctx.__originalRestore = ctx.restore;\n  ctx.__originalRotate = ctx.rotate;\n  ctx.__originalScale = ctx.scale;\n  ctx.__originalTranslate = ctx.translate;\n  ctx.__originalTransform = ctx.transform;\n  ctx.__originalSetTransform = ctx.setTransform;\n  ctx.__originalResetTransform = ctx.resetTransform;\n  ctx.__originalClip = ctx.clip;\n  ctx.__originalMoveTo = ctx.moveTo;\n  ctx.__originalLineTo = ctx.lineTo;\n  ctx.__originalBezierCurveTo = ctx.bezierCurveTo;\n  ctx.__originalRect = ctx.rect;\n  ctx.__originalClosePath = ctx.closePath;\n  ctx.__originalBeginPath = ctx.beginPath;\n  ctx._removeMirroring = () => {\n    ctx.save = ctx.__originalSave;\n    ctx.restore = ctx.__originalRestore;\n    ctx.rotate = ctx.__originalRotate;\n    ctx.scale = ctx.__originalScale;\n    ctx.translate = ctx.__originalTranslate;\n    ctx.transform = ctx.__originalTransform;\n    ctx.setTransform = ctx.__originalSetTransform;\n    ctx.resetTransform = ctx.__originalResetTransform;\n    ctx.clip = ctx.__originalClip;\n    ctx.moveTo = ctx.__originalMoveTo;\n    ctx.lineTo = ctx.__originalLineTo;\n    ctx.bezierCurveTo = ctx.__originalBezierCurveTo;\n    ctx.rect = ctx.__originalRect;\n    ctx.closePath = ctx.__originalClosePath;\n    ctx.beginPath = ctx.__originalBeginPath;\n    delete ctx._removeMirroring;\n  };\n  ctx.save = function ctxSave() {\n    destCtx.save();\n    this.__originalSave();\n  };\n  ctx.restore = function ctxRestore() {\n    destCtx.restore();\n    this.__originalRestore();\n  };\n  ctx.translate = function ctxTranslate(x, y) {\n    destCtx.translate(x, y);\n    this.__originalTranslate(x, y);\n  };\n  ctx.scale = function ctxScale(x, y) {\n    destCtx.scale(x, y);\n    this.__originalScale(x, y);\n  };\n  ctx.transform = function ctxTransform(a, b, c, d, e, f) {\n    destCtx.transform(a, b, c, d, e, f);\n    this.__originalTransform(a, b, c, d, e, f);\n  };\n  ctx.setTransform = function ctxSetTransform(a, b, c, d, e, f) {\n    destCtx.setTransform(a, b, c, d, e, f);\n    this.__originalSetTransform(a, b, c, d, e, f);\n  };\n  ctx.resetTransform = function ctxResetTransform() {\n    destCtx.resetTransform();\n    this.__originalResetTransform();\n  };\n  ctx.rotate = function ctxRotate(angle) {\n    destCtx.rotate(angle);\n    this.__originalRotate(angle);\n  };\n  ctx.clip = function ctxRotate(rule) {\n    destCtx.clip(rule);\n    this.__originalClip(rule);\n  };\n  ctx.moveTo = function (x, y) {\n    destCtx.moveTo(x, y);\n    this.__originalMoveTo(x, y);\n  };\n  ctx.lineTo = function (x, y) {\n    destCtx.lineTo(x, y);\n    this.__originalLineTo(x, y);\n  };\n  ctx.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) {\n    destCtx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);\n    this.__originalBezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);\n  };\n  ctx.rect = function (x, y, width, height) {\n    destCtx.rect(x, y, width, height);\n    this.__originalRect(x, y, width, height);\n  };\n  ctx.closePath = function () {\n    destCtx.closePath();\n    this.__originalClosePath();\n  };\n  ctx.beginPath = function () {\n    destCtx.beginPath();\n    this.__originalBeginPath();\n  };\n}\nclass CachedCanvases {\n  constructor(canvasFactory) {\n    this.canvasFactory = canvasFactory;\n    this.cache = Object.create(null);\n  }\n  getCanvas(id, width, height) {\n    let canvasEntry;\n    if (this.cache[id] !== undefined) {\n      canvasEntry = this.cache[id];\n      this.canvasFactory.reset(canvasEntry, width, height);\n    } else {\n      canvasEntry = this.canvasFactory.create(width, height);\n      this.cache[id] = canvasEntry;\n    }\n    return canvasEntry;\n  }\n  delete(id) {\n    delete this.cache[id];\n  }\n  clear() {\n    for (const id in this.cache) {\n      const canvasEntry = this.cache[id];\n      this.canvasFactory.destroy(canvasEntry);\n      delete this.cache[id];\n    }\n  }\n}\nfunction drawImageAtIntegerCoords(ctx, srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH) {\n  const [a, b, c, d, tx, ty] = (0,display_utils.getCurrentTransform)(ctx);\n  if (b === 0 && c === 0) {\n    const tlX = destX * a + tx;\n    const rTlX = Math.round(tlX);\n    const tlY = destY * d + ty;\n    const rTlY = Math.round(tlY);\n    const brX = (destX + destW) * a + tx;\n    const rWidth = Math.abs(Math.round(brX) - rTlX) || 1;\n    const brY = (destY + destH) * d + ty;\n    const rHeight = Math.abs(Math.round(brY) - rTlY) || 1;\n    ctx.setTransform(Math.sign(a), 0, 0, Math.sign(d), rTlX, rTlY);\n    ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rWidth, rHeight);\n    ctx.setTransform(a, b, c, d, tx, ty);\n    return [rWidth, rHeight];\n  }\n  if (a === 0 && d === 0) {\n    const tlX = destY * c + tx;\n    const rTlX = Math.round(tlX);\n    const tlY = destX * b + ty;\n    const rTlY = Math.round(tlY);\n    const brX = (destY + destH) * c + tx;\n    const rWidth = Math.abs(Math.round(brX) - rTlX) || 1;\n    const brY = (destX + destW) * b + ty;\n    const rHeight = Math.abs(Math.round(brY) - rTlY) || 1;\n    ctx.setTransform(0, Math.sign(b), Math.sign(c), 0, rTlX, rTlY);\n    ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rHeight, rWidth);\n    ctx.setTransform(a, b, c, d, tx, ty);\n    return [rHeight, rWidth];\n  }\n  ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH);\n  const scaleX = Math.hypot(a, b);\n  const scaleY = Math.hypot(c, d);\n  return [scaleX * destW, scaleY * destH];\n}\nfunction compileType3Glyph(imgData) {\n  const {\n    width,\n    height\n  } = imgData;\n  if (width > MAX_SIZE_TO_COMPILE || height > MAX_SIZE_TO_COMPILE) {\n    return null;\n  }\n  const POINT_TO_PROCESS_LIMIT = 1000;\n  const POINT_TYPES = new Uint8Array([0, 2, 4, 0, 1, 0, 5, 4, 8, 10, 0, 8, 0, 2, 1, 0]);\n  const width1 = width + 1;\n  let points = new Uint8Array(width1 * (height + 1));\n  let i, j, j0;\n  const lineSize = width + 7 & ~7;\n  let data = new Uint8Array(lineSize * height),\n    pos = 0;\n  for (const elem of imgData.data) {\n    let mask = 128;\n    while (mask > 0) {\n      data[pos++] = elem & mask ? 0 : 255;\n      mask >>= 1;\n    }\n  }\n  let count = 0;\n  pos = 0;\n  if (data[pos] !== 0) {\n    points[0] = 1;\n    ++count;\n  }\n  for (j = 1; j < width; j++) {\n    if (data[pos] !== data[pos + 1]) {\n      points[j] = data[pos] ? 2 : 1;\n      ++count;\n    }\n    pos++;\n  }\n  if (data[pos] !== 0) {\n    points[j] = 2;\n    ++count;\n  }\n  for (i = 1; i < height; i++) {\n    pos = i * lineSize;\n    j0 = i * width1;\n    if (data[pos - lineSize] !== data[pos]) {\n      points[j0] = data[pos] ? 1 : 8;\n      ++count;\n    }\n    let sum = (data[pos] ? 4 : 0) + (data[pos - lineSize] ? 8 : 0);\n    for (j = 1; j < width; j++) {\n      sum = (sum >> 2) + (data[pos + 1] ? 4 : 0) + (data[pos - lineSize + 1] ? 8 : 0);\n      if (POINT_TYPES[sum]) {\n        points[j0 + j] = POINT_TYPES[sum];\n        ++count;\n      }\n      pos++;\n    }\n    if (data[pos - lineSize] !== data[pos]) {\n      points[j0 + j] = data[pos] ? 2 : 4;\n      ++count;\n    }\n    if (count > POINT_TO_PROCESS_LIMIT) {\n      return null;\n    }\n  }\n  pos = lineSize * (height - 1);\n  j0 = i * width1;\n  if (data[pos] !== 0) {\n    points[j0] = 8;\n    ++count;\n  }\n  for (j = 1; j < width; j++) {\n    if (data[pos] !== data[pos + 1]) {\n      points[j0 + j] = data[pos] ? 4 : 8;\n      ++count;\n    }\n    pos++;\n  }\n  if (data[pos] !== 0) {\n    points[j0 + j] = 4;\n    ++count;\n  }\n  if (count > POINT_TO_PROCESS_LIMIT) {\n    return null;\n  }\n  const steps = new Int32Array([0, width1, -1, 0, -width1, 0, 0, 0, 1]);\n  const path = new Path2D();\n  for (i = 0; count && i <= height; i++) {\n    let p = i * width1;\n    const end = p + width;\n    while (p < end && !points[p]) {\n      p++;\n    }\n    if (p === end) {\n      continue;\n    }\n    path.moveTo(p % width1, i);\n    const p0 = p;\n    let type = points[p];\n    do {\n      const step = steps[type];\n      do {\n        p += step;\n      } while (!points[p]);\n      const pp = points[p];\n      if (pp !== 5 && pp !== 10) {\n        type = pp;\n        points[p] = 0;\n      } else {\n        type = pp & 0x33 * type >> 4;\n        points[p] &= type >> 2 | type << 2;\n      }\n      path.lineTo(p % width1, p / width1 | 0);\n      if (!points[p]) {\n        --count;\n      }\n    } while (p0 !== p);\n    --i;\n  }\n  data = null;\n  points = null;\n  const drawOutline = function (c) {\n    c.save();\n    c.scale(1 / width, -1 / height);\n    c.translate(0, -height);\n    c.fill(path);\n    c.beginPath();\n    c.restore();\n  };\n  return drawOutline;\n}\nclass CanvasExtraState {\n  constructor(width, height) {\n    this.alphaIsShape = false;\n    this.fontSize = 0;\n    this.fontSizeScale = 1;\n    this.textMatrix = util.IDENTITY_MATRIX;\n    this.textMatrixScale = 1;\n    this.fontMatrix = util.FONT_IDENTITY_MATRIX;\n    this.leading = 0;\n    this.x = 0;\n    this.y = 0;\n    this.lineX = 0;\n    this.lineY = 0;\n    this.charSpacing = 0;\n    this.wordSpacing = 0;\n    this.textHScale = 1;\n    this.textRenderingMode = util.TextRenderingMode.FILL;\n    this.textRise = 0;\n    this.fillColor = \"#000000\";\n    this.strokeColor = \"#000000\";\n    this.patternFill = false;\n    this.fillAlpha = 1;\n    this.strokeAlpha = 1;\n    this.lineWidth = 1;\n    this.activeSMask = null;\n    this.transferMaps = \"none\";\n    this.startNewPathAndClipBox([0, 0, width, height]);\n  }\n  clone() {\n    const clone = Object.create(this);\n    clone.clipBox = this.clipBox.slice();\n    return clone;\n  }\n  setCurrentPoint(x, y) {\n    this.x = x;\n    this.y = y;\n  }\n  updatePathMinMax(transform, x, y) {\n    [x, y] = util.Util.applyTransform([x, y], transform);\n    this.minX = Math.min(this.minX, x);\n    this.minY = Math.min(this.minY, y);\n    this.maxX = Math.max(this.maxX, x);\n    this.maxY = Math.max(this.maxY, y);\n  }\n  updateRectMinMax(transform, rect) {\n    const p1 = util.Util.applyTransform(rect, transform);\n    const p2 = util.Util.applyTransform(rect.slice(2), transform);\n    const p3 = util.Util.applyTransform([rect[0], rect[3]], transform);\n    const p4 = util.Util.applyTransform([rect[2], rect[1]], transform);\n    this.minX = Math.min(this.minX, p1[0], p2[0], p3[0], p4[0]);\n    this.minY = Math.min(this.minY, p1[1], p2[1], p3[1], p4[1]);\n    this.maxX = Math.max(this.maxX, p1[0], p2[0], p3[0], p4[0]);\n    this.maxY = Math.max(this.maxY, p1[1], p2[1], p3[1], p4[1]);\n  }\n  updateScalingPathMinMax(transform, minMax) {\n    util.Util.scaleMinMax(transform, minMax);\n    this.minX = Math.min(this.minX, minMax[0]);\n    this.minY = Math.min(this.minY, minMax[1]);\n    this.maxX = Math.max(this.maxX, minMax[2]);\n    this.maxY = Math.max(this.maxY, minMax[3]);\n  }\n  updateCurvePathMinMax(transform, x0, y0, x1, y1, x2, y2, x3, y3, minMax) {\n    const box = util.Util.bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3, minMax);\n    if (minMax) {\n      return;\n    }\n    this.updateRectMinMax(transform, box);\n  }\n  getPathBoundingBox(pathType = PathType.FILL, transform = null) {\n    const box = [this.minX, this.minY, this.maxX, this.maxY];\n    if (pathType === PathType.STROKE) {\n      if (!transform) {\n        (0,util.unreachable)(\"Stroke bounding box must include transform.\");\n      }\n      const scale = util.Util.singularValueDecompose2dScale(transform);\n      const xStrokePad = scale[0] * this.lineWidth / 2;\n      const yStrokePad = scale[1] * this.lineWidth / 2;\n      box[0] -= xStrokePad;\n      box[1] -= yStrokePad;\n      box[2] += xStrokePad;\n      box[3] += yStrokePad;\n    }\n    return box;\n  }\n  updateClipFromPath() {\n    const intersect = util.Util.intersect(this.clipBox, this.getPathBoundingBox());\n    this.startNewPathAndClipBox(intersect || [0, 0, 0, 0]);\n  }\n  isEmptyClip() {\n    return this.minX === Infinity;\n  }\n  startNewPathAndClipBox(box) {\n    this.clipBox = box;\n    this.minX = Infinity;\n    this.minY = Infinity;\n    this.maxX = 0;\n    this.maxY = 0;\n  }\n  getClippedPathBoundingBox(pathType = PathType.FILL, transform = null) {\n    return util.Util.intersect(this.clipBox, this.getPathBoundingBox(pathType, transform));\n  }\n}\nfunction putBinaryImageData(ctx, imgData) {\n  if (typeof ImageData !== \"undefined\" && imgData instanceof ImageData) {\n    ctx.putImageData(imgData, 0, 0);\n    return;\n  }\n  const height = imgData.height,\n    width = imgData.width;\n  const partialChunkHeight = height % FULL_CHUNK_HEIGHT;\n  const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT;\n  const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1;\n  const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT);\n  let srcPos = 0,\n    destPos;\n  const src = imgData.data;\n  const dest = chunkImgData.data;\n  let i, j, thisChunkHeight, elemsInThisChunk;\n  if (imgData.kind === util.ImageKind.GRAYSCALE_1BPP) {\n    const srcLength = src.byteLength;\n    const dest32 = new Uint32Array(dest.buffer, 0, dest.byteLength >> 2);\n    const dest32DataLength = dest32.length;\n    const fullSrcDiff = width + 7 >> 3;\n    const white = 0xffffffff;\n    const black = util.FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff;\n    for (i = 0; i < totalChunks; i++) {\n      thisChunkHeight = i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight;\n      destPos = 0;\n      for (j = 0; j < thisChunkHeight; j++) {\n        const srcDiff = srcLength - srcPos;\n        let k = 0;\n        const kEnd = srcDiff > fullSrcDiff ? width : srcDiff * 8 - 7;\n        const kEndUnrolled = kEnd & ~7;\n        let mask = 0;\n        let srcByte = 0;\n        for (; k < kEndUnrolled; k += 8) {\n          srcByte = src[srcPos++];\n          dest32[destPos++] = srcByte & 128 ? white : black;\n          dest32[destPos++] = srcByte & 64 ? white : black;\n          dest32[destPos++] = srcByte & 32 ? white : black;\n          dest32[destPos++] = srcByte & 16 ? white : black;\n          dest32[destPos++] = srcByte & 8 ? white : black;\n          dest32[destPos++] = srcByte & 4 ? white : black;\n          dest32[destPos++] = srcByte & 2 ? white : black;\n          dest32[destPos++] = srcByte & 1 ? white : black;\n        }\n        for (; k < kEnd; k++) {\n          if (mask === 0) {\n            srcByte = src[srcPos++];\n            mask = 128;\n          }\n          dest32[destPos++] = srcByte & mask ? white : black;\n          mask >>= 1;\n        }\n      }\n      while (destPos < dest32DataLength) {\n        dest32[destPos++] = 0;\n      }\n      ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT);\n    }\n  } else if (imgData.kind === util.ImageKind.RGBA_32BPP) {\n    j = 0;\n    elemsInThisChunk = width * FULL_CHUNK_HEIGHT * 4;\n    for (i = 0; i < fullChunks; i++) {\n      dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk));\n      srcPos += elemsInThisChunk;\n      ctx.putImageData(chunkImgData, 0, j);\n      j += FULL_CHUNK_HEIGHT;\n    }\n    if (i < totalChunks) {\n      elemsInThisChunk = width * partialChunkHeight * 4;\n      dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk));\n      ctx.putImageData(chunkImgData, 0, j);\n    }\n  } else if (imgData.kind === util.ImageKind.RGB_24BPP) {\n    thisChunkHeight = FULL_CHUNK_HEIGHT;\n    elemsInThisChunk = width * thisChunkHeight;\n    for (i = 0; i < totalChunks; i++) {\n      if (i >= fullChunks) {\n        thisChunkHeight = partialChunkHeight;\n        elemsInThisChunk = width * thisChunkHeight;\n      }\n      destPos = 0;\n      for (j = elemsInThisChunk; j--;) {\n        dest[destPos++] = src[srcPos++];\n        dest[destPos++] = src[srcPos++];\n        dest[destPos++] = src[srcPos++];\n        dest[destPos++] = 255;\n      }\n      ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT);\n    }\n  } else {\n    throw new Error(`bad image kind: ${imgData.kind}`);\n  }\n}\nfunction putBinaryImageMask(ctx, imgData) {\n  if (imgData.bitmap) {\n    ctx.drawImage(imgData.bitmap, 0, 0);\n    return;\n  }\n  const height = imgData.height,\n    width = imgData.width;\n  const partialChunkHeight = height % FULL_CHUNK_HEIGHT;\n  const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT;\n  const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1;\n  const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT);\n  let srcPos = 0;\n  const src = imgData.data;\n  const dest = chunkImgData.data;\n  for (let i = 0; i < totalChunks; i++) {\n    const thisChunkHeight = i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight;\n    ({\n      srcPos\n    } = convertBlackAndWhiteToRGBA({\n      src,\n      srcPos,\n      dest,\n      width,\n      height: thisChunkHeight,\n      nonBlackColor: 0\n    }));\n    ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT);\n  }\n}\nfunction copyCtxState(sourceCtx, destCtx) {\n  const properties = [\"strokeStyle\", \"fillStyle\", \"fillRule\", \"globalAlpha\", \"lineWidth\", \"lineCap\", \"lineJoin\", \"miterLimit\", \"globalCompositeOperation\", \"font\", \"filter\"];\n  for (const property of properties) {\n    if (sourceCtx[property] !== undefined) {\n      destCtx[property] = sourceCtx[property];\n    }\n  }\n  if (sourceCtx.setLineDash !== undefined) {\n    destCtx.setLineDash(sourceCtx.getLineDash());\n    destCtx.lineDashOffset = sourceCtx.lineDashOffset;\n  }\n}\nfunction resetCtxToDefault(ctx) {\n  ctx.strokeStyle = ctx.fillStyle = \"#000000\";\n  ctx.fillRule = \"nonzero\";\n  ctx.globalAlpha = 1;\n  ctx.lineWidth = 1;\n  ctx.lineCap = \"butt\";\n  ctx.lineJoin = \"miter\";\n  ctx.miterLimit = 10;\n  ctx.globalCompositeOperation = \"source-over\";\n  ctx.font = \"10px sans-serif\";\n  if (ctx.setLineDash !== undefined) {\n    ctx.setLineDash([]);\n    ctx.lineDashOffset = 0;\n  }\n  if (!util.isNodeJS) {\n    const {\n      filter\n    } = ctx;\n    if (filter !== \"none\" && filter !== \"\") {\n      ctx.filter = \"none\";\n    }\n  }\n}\nfunction composeSMaskBackdrop(bytes, r0, g0, b0) {\n  const length = bytes.length;\n  for (let i = 3; i < length; i += 4) {\n    const alpha = bytes[i];\n    if (alpha === 0) {\n      bytes[i - 3] = r0;\n      bytes[i - 2] = g0;\n      bytes[i - 1] = b0;\n    } else if (alpha < 255) {\n      const alpha_ = 255 - alpha;\n      bytes[i - 3] = bytes[i - 3] * alpha + r0 * alpha_ >> 8;\n      bytes[i - 2] = bytes[i - 2] * alpha + g0 * alpha_ >> 8;\n      bytes[i - 1] = bytes[i - 1] * alpha + b0 * alpha_ >> 8;\n    }\n  }\n}\nfunction composeSMaskAlpha(maskData, layerData, transferMap) {\n  const length = maskData.length;\n  const scale = 1 / 255;\n  for (let i = 3; i < length; i += 4) {\n    const alpha = transferMap ? transferMap[maskData[i]] : maskData[i];\n    layerData[i] = layerData[i] * alpha * scale | 0;\n  }\n}\nfunction composeSMaskLuminosity(maskData, layerData, transferMap) {\n  const length = maskData.length;\n  for (let i = 3; i < length; i += 4) {\n    const y = maskData[i - 3] * 77 + maskData[i - 2] * 152 + maskData[i - 1] * 28;\n    layerData[i] = transferMap ? layerData[i] * transferMap[y >> 8] >> 8 : layerData[i] * y >> 16;\n  }\n}\nfunction genericComposeSMask(maskCtx, layerCtx, width, height, subtype, backdrop, transferMap, layerOffsetX, layerOffsetY, maskOffsetX, maskOffsetY) {\n  const hasBackdrop = !!backdrop;\n  const r0 = hasBackdrop ? backdrop[0] : 0;\n  const g0 = hasBackdrop ? backdrop[1] : 0;\n  const b0 = hasBackdrop ? backdrop[2] : 0;\n  const composeFn = subtype === \"Luminosity\" ? composeSMaskLuminosity : composeSMaskAlpha;\n  const PIXELS_TO_PROCESS = 1048576;\n  const chunkSize = Math.min(height, Math.ceil(PIXELS_TO_PROCESS / width));\n  for (let row = 0; row < height; row += chunkSize) {\n    const chunkHeight = Math.min(chunkSize, height - row);\n    const maskData = maskCtx.getImageData(layerOffsetX - maskOffsetX, row + (layerOffsetY - maskOffsetY), width, chunkHeight);\n    const layerData = layerCtx.getImageData(layerOffsetX, row + layerOffsetY, width, chunkHeight);\n    if (hasBackdrop) {\n      composeSMaskBackdrop(maskData.data, r0, g0, b0);\n    }\n    composeFn(maskData.data, layerData.data, transferMap);\n    layerCtx.putImageData(layerData, layerOffsetX, row + layerOffsetY);\n  }\n}\nfunction composeSMask(ctx, smask, layerCtx, layerBox) {\n  const layerOffsetX = layerBox[0];\n  const layerOffsetY = layerBox[1];\n  const layerWidth = layerBox[2] - layerOffsetX;\n  const layerHeight = layerBox[3] - layerOffsetY;\n  if (layerWidth === 0 || layerHeight === 0) {\n    return;\n  }\n  genericComposeSMask(smask.context, layerCtx, layerWidth, layerHeight, smask.subtype, smask.backdrop, smask.transferMap, layerOffsetX, layerOffsetY, smask.offsetX, smask.offsetY);\n  ctx.save();\n  ctx.globalAlpha = 1;\n  ctx.globalCompositeOperation = \"source-over\";\n  ctx.setTransform(1, 0, 0, 1, 0, 0);\n  ctx.drawImage(layerCtx.canvas, 0, 0);\n  ctx.restore();\n}\nfunction getImageSmoothingEnabled(transform, interpolate) {\n  const scale = util.Util.singularValueDecompose2dScale(transform);\n  scale[0] = Math.fround(scale[0]);\n  scale[1] = Math.fround(scale[1]);\n  const actualScale = Math.fround((globalThis.devicePixelRatio || 1) * display_utils.PixelsPerInch.PDF_TO_CSS_UNITS);\n  if (interpolate !== undefined) {\n    return interpolate;\n  } else if (scale[0] <= actualScale || scale[1] <= actualScale) {\n    return true;\n  }\n  return false;\n}\nconst LINE_CAP_STYLES = [\"butt\", \"round\", \"square\"];\nconst LINE_JOIN_STYLES = [\"miter\", \"round\", \"bevel\"];\nconst NORMAL_CLIP = {};\nconst EO_CLIP = {};\nclass CanvasGraphics {\n  constructor(canvasCtx, commonObjs, objs, canvasFactory, filterFactory, {\n    optionalContentConfig,\n    markedContentStack = null\n  }, annotationCanvasMap, pageColors) {\n    this.ctx = canvasCtx;\n    this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height);\n    this.stateStack = [];\n    this.pendingClip = null;\n    this.pendingEOFill = false;\n    this.res = null;\n    this.xobjs = null;\n    this.commonObjs = commonObjs;\n    this.objs = objs;\n    this.canvasFactory = canvasFactory;\n    this.filterFactory = filterFactory;\n    this.groupStack = [];\n    this.processingType3 = null;\n    this.baseTransform = null;\n    this.baseTransformStack = [];\n    this.groupLevel = 0;\n    this.smaskStack = [];\n    this.smaskCounter = 0;\n    this.tempSMask = null;\n    this.suspendedCtx = null;\n    this.contentVisible = true;\n    this.markedContentStack = markedContentStack || [];\n    this.optionalContentConfig = optionalContentConfig;\n    this.cachedCanvases = new CachedCanvases(this.canvasFactory);\n    this.cachedPatterns = new Map();\n    this.annotationCanvasMap = annotationCanvasMap;\n    this.viewportScale = 1;\n    this.outputScaleX = 1;\n    this.outputScaleY = 1;\n    this.pageColors = pageColors;\n    this._cachedScaleForStroking = [-1, 0];\n    this._cachedGetSinglePixelWidth = null;\n    this._cachedBitmapsMap = new Map();\n  }\n  getObject(data, fallback = null) {\n    if (typeof data === \"string\") {\n      return data.startsWith(\"g_\") ? this.commonObjs.get(data) : this.objs.get(data);\n    }\n    return fallback;\n  }\n  beginDrawing({\n    transform,\n    viewport,\n    transparency = false,\n    background = null\n  }) {\n    const width = this.ctx.canvas.width;\n    const height = this.ctx.canvas.height;\n    const savedFillStyle = this.ctx.fillStyle;\n    this.ctx.fillStyle = background || \"#ffffff\";\n    this.ctx.fillRect(0, 0, width, height);\n    this.ctx.fillStyle = savedFillStyle;\n    if (transparency) {\n      const transparentCanvas = this.cachedCanvases.getCanvas(\"transparent\", width, height);\n      this.compositeCtx = this.ctx;\n      this.transparentCanvas = transparentCanvas.canvas;\n      this.ctx = transparentCanvas.context;\n      this.ctx.save();\n      this.ctx.transform(...(0,display_utils.getCurrentTransform)(this.compositeCtx));\n    }\n    this.ctx.save();\n    resetCtxToDefault(this.ctx);\n    if (transform) {\n      this.ctx.transform(...transform);\n      this.outputScaleX = transform[0];\n      this.outputScaleY = transform[0];\n    }\n    this.ctx.transform(...viewport.transform);\n    this.viewportScale = viewport.scale;\n    this.baseTransform = (0,display_utils.getCurrentTransform)(this.ctx);\n  }\n  executeOperatorList(operatorList, executionStartIdx, continueCallback, stepper) {\n    const argsArray = operatorList.argsArray;\n    const fnArray = operatorList.fnArray;\n    let i = executionStartIdx || 0;\n    const argsArrayLen = argsArray.length;\n    if (argsArrayLen === i) {\n      return i;\n    }\n    const chunkOperations = argsArrayLen - i > EXECUTION_STEPS && typeof continueCallback === \"function\";\n    const endTime = chunkOperations ? Date.now() + EXECUTION_TIME : 0;\n    let steps = 0;\n    const commonObjs = this.commonObjs;\n    const objs = this.objs;\n    let fnId;\n    while (true) {\n      if (stepper !== undefined && i === stepper.nextBreakPoint) {\n        stepper.breakIt(i, continueCallback);\n        return i;\n      }\n      fnId = fnArray[i];\n      if (fnId !== util.OPS.dependency) {\n        this[fnId].apply(this, argsArray[i]);\n      } else {\n        for (const depObjId of argsArray[i]) {\n          const objsPool = depObjId.startsWith(\"g_\") ? commonObjs : objs;\n          if (!objsPool.has(depObjId)) {\n            objsPool.get(depObjId, continueCallback);\n            return i;\n          }\n        }\n      }\n      i++;\n      if (i === argsArrayLen) {\n        return i;\n      }\n      if (chunkOperations && ++steps > EXECUTION_STEPS) {\n        if (Date.now() > endTime) {\n          continueCallback();\n          return i;\n        }\n        steps = 0;\n      }\n    }\n  }\n  #restoreInitialState() {\n    while (this.stateStack.length || this.inSMaskMode) {\n      this.restore();\n    }\n    this.ctx.restore();\n    if (this.transparentCanvas) {\n      this.ctx = this.compositeCtx;\n      this.ctx.save();\n      this.ctx.setTransform(1, 0, 0, 1, 0, 0);\n      this.ctx.drawImage(this.transparentCanvas, 0, 0);\n      this.ctx.restore();\n      this.transparentCanvas = null;\n    }\n  }\n  endDrawing() {\n    this.#restoreInitialState();\n    this.cachedCanvases.clear();\n    this.cachedPatterns.clear();\n    for (const cache of this._cachedBitmapsMap.values()) {\n      for (const canvas of cache.values()) {\n        if (typeof HTMLCanvasElement !== \"undefined\" && canvas instanceof HTMLCanvasElement) {\n          canvas.width = canvas.height = 0;\n        }\n      }\n      cache.clear();\n    }\n    this._cachedBitmapsMap.clear();\n    this.#drawFilter();\n  }\n  #drawFilter() {\n    if (this.pageColors) {\n      const hcmFilterId = this.filterFactory.addHCMFilter(this.pageColors.foreground, this.pageColors.background);\n      if (hcmFilterId !== \"none\") {\n        const savedFilter = this.ctx.filter;\n        this.ctx.filter = hcmFilterId;\n        this.ctx.drawImage(this.ctx.canvas, 0, 0);\n        this.ctx.filter = savedFilter;\n      }\n    }\n  }\n  _scaleImage(img, inverseTransform) {\n    const width = img.width;\n    const height = img.height;\n    let widthScale = Math.max(Math.hypot(inverseTransform[0], inverseTransform[1]), 1);\n    let heightScale = Math.max(Math.hypot(inverseTransform[2], inverseTransform[3]), 1);\n    let paintWidth = width,\n      paintHeight = height;\n    let tmpCanvasId = \"prescale1\";\n    let tmpCanvas, tmpCtx;\n    while (widthScale > 2 && paintWidth > 1 || heightScale > 2 && paintHeight > 1) {\n      let newWidth = paintWidth,\n        newHeight = paintHeight;\n      if (widthScale > 2 && paintWidth > 1) {\n        newWidth = paintWidth >= 16384 ? Math.floor(paintWidth / 2) - 1 || 1 : Math.ceil(paintWidth / 2);\n        widthScale /= paintWidth / newWidth;\n      }\n      if (heightScale > 2 && paintHeight > 1) {\n        newHeight = paintHeight >= 16384 ? Math.floor(paintHeight / 2) - 1 || 1 : Math.ceil(paintHeight) / 2;\n        heightScale /= paintHeight / newHeight;\n      }\n      tmpCanvas = this.cachedCanvases.getCanvas(tmpCanvasId, newWidth, newHeight);\n      tmpCtx = tmpCanvas.context;\n      tmpCtx.clearRect(0, 0, newWidth, newHeight);\n      tmpCtx.drawImage(img, 0, 0, paintWidth, paintHeight, 0, 0, newWidth, newHeight);\n      img = tmpCanvas.canvas;\n      paintWidth = newWidth;\n      paintHeight = newHeight;\n      tmpCanvasId = tmpCanvasId === \"prescale1\" ? \"prescale2\" : \"prescale1\";\n    }\n    return {\n      img,\n      paintWidth,\n      paintHeight\n    };\n  }\n  _createMaskCanvas(img) {\n    const ctx = this.ctx;\n    const {\n      width,\n      height\n    } = img;\n    const fillColor = this.current.fillColor;\n    const isPatternFill = this.current.patternFill;\n    const currentTransform = (0,display_utils.getCurrentTransform)(ctx);\n    let cache, cacheKey, scaled, maskCanvas;\n    if ((img.bitmap || img.data) && img.count > 1) {\n      const mainKey = img.bitmap || img.data.buffer;\n      cacheKey = JSON.stringify(isPatternFill ? currentTransform : [currentTransform.slice(0, 4), fillColor]);\n      cache = this._cachedBitmapsMap.get(mainKey);\n      if (!cache) {\n        cache = new Map();\n        this._cachedBitmapsMap.set(mainKey, cache);\n      }\n      const cachedImage = cache.get(cacheKey);\n      if (cachedImage && !isPatternFill) {\n        const offsetX = Math.round(Math.min(currentTransform[0], currentTransform[2]) + currentTransform[4]);\n        const offsetY = Math.round(Math.min(currentTransform[1], currentTransform[3]) + currentTransform[5]);\n        return {\n          canvas: cachedImage,\n          offsetX,\n          offsetY\n        };\n      }\n      scaled = cachedImage;\n    }\n    if (!scaled) {\n      maskCanvas = this.cachedCanvases.getCanvas(\"maskCanvas\", width, height);\n      putBinaryImageMask(maskCanvas.context, img);\n    }\n    let maskToCanvas = util.Util.transform(currentTransform, [1 / width, 0, 0, -1 / height, 0, 0]);\n    maskToCanvas = util.Util.transform(maskToCanvas, [1, 0, 0, 1, 0, -height]);\n    const [minX, minY, maxX, maxY] = util.Util.getAxialAlignedBoundingBox([0, 0, width, height], maskToCanvas);\n    const drawnWidth = Math.round(maxX - minX) || 1;\n    const drawnHeight = Math.round(maxY - minY) || 1;\n    const fillCanvas = this.cachedCanvases.getCanvas(\"fillCanvas\", drawnWidth, drawnHeight);\n    const fillCtx = fillCanvas.context;\n    const offsetX = minX;\n    const offsetY = minY;\n    fillCtx.translate(-offsetX, -offsetY);\n    fillCtx.transform(...maskToCanvas);\n    if (!scaled) {\n      scaled = this._scaleImage(maskCanvas.canvas, (0,display_utils.getCurrentTransformInverse)(fillCtx));\n      scaled = scaled.img;\n      if (cache && isPatternFill) {\n        cache.set(cacheKey, scaled);\n      }\n    }\n    fillCtx.imageSmoothingEnabled = getImageSmoothingEnabled((0,display_utils.getCurrentTransform)(fillCtx), img.interpolate);\n    drawImageAtIntegerCoords(fillCtx, scaled, 0, 0, scaled.width, scaled.height, 0, 0, width, height);\n    fillCtx.globalCompositeOperation = \"source-in\";\n    const inverse = util.Util.transform((0,display_utils.getCurrentTransformInverse)(fillCtx), [1, 0, 0, 1, -offsetX, -offsetY]);\n    fillCtx.fillStyle = isPatternFill ? fillColor.getPattern(ctx, this, inverse, PathType.FILL) : fillColor;\n    fillCtx.fillRect(0, 0, width, height);\n    if (cache && !isPatternFill) {\n      this.cachedCanvases.delete(\"fillCanvas\");\n      cache.set(cacheKey, fillCanvas.canvas);\n    }\n    return {\n      canvas: fillCanvas.canvas,\n      offsetX: Math.round(offsetX),\n      offsetY: Math.round(offsetY)\n    };\n  }\n  setLineWidth(width) {\n    if (width !== this.current.lineWidth) {\n      this._cachedScaleForStroking[0] = -1;\n    }\n    this.current.lineWidth = width;\n    this.ctx.lineWidth = width;\n  }\n  setLineCap(style) {\n    this.ctx.lineCap = LINE_CAP_STYLES[style];\n  }\n  setLineJoin(style) {\n    this.ctx.lineJoin = LINE_JOIN_STYLES[style];\n  }\n  setMiterLimit(limit) {\n    this.ctx.miterLimit = limit;\n  }\n  setDash(dashArray, dashPhase) {\n    const ctx = this.ctx;\n    if (ctx.setLineDash !== undefined) {\n      ctx.setLineDash(dashArray);\n      ctx.lineDashOffset = dashPhase;\n    }\n  }\n  setRenderingIntent(intent) {}\n  setFlatness(flatness) {}\n  setGState(states) {\n    for (const [key, value] of states) {\n      switch (key) {\n        case \"LW\":\n          this.setLineWidth(value);\n          break;\n        case \"LC\":\n          this.setLineCap(value);\n          break;\n        case \"LJ\":\n          this.setLineJoin(value);\n          break;\n        case \"ML\":\n          this.setMiterLimit(value);\n          break;\n        case \"D\":\n          this.setDash(value[0], value[1]);\n          break;\n        case \"RI\":\n          this.setRenderingIntent(value);\n          break;\n        case \"FL\":\n          this.setFlatness(value);\n          break;\n        case \"Font\":\n          this.setFont(value[0], value[1]);\n          break;\n        case \"CA\":\n          this.current.strokeAlpha = value;\n          break;\n        case \"ca\":\n          this.current.fillAlpha = value;\n          this.ctx.globalAlpha = value;\n          break;\n        case \"BM\":\n          this.ctx.globalCompositeOperation = value;\n          break;\n        case \"SMask\":\n          this.current.activeSMask = value ? this.tempSMask : null;\n          this.tempSMask = null;\n          this.checkSMaskState();\n          break;\n        case \"TR\":\n          this.ctx.filter = this.current.transferMaps = this.filterFactory.addFilter(value);\n          break;\n      }\n    }\n  }\n  get inSMaskMode() {\n    return !!this.suspendedCtx;\n  }\n  checkSMaskState() {\n    const inSMaskMode = this.inSMaskMode;\n    if (this.current.activeSMask && !inSMaskMode) {\n      this.beginSMaskMode();\n    } else if (!this.current.activeSMask && inSMaskMode) {\n      this.endSMaskMode();\n    }\n  }\n  beginSMaskMode() {\n    if (this.inSMaskMode) {\n      throw new Error(\"beginSMaskMode called while already in smask mode\");\n    }\n    const drawnWidth = this.ctx.canvas.width;\n    const drawnHeight = this.ctx.canvas.height;\n    const cacheId = \"smaskGroupAt\" + this.groupLevel;\n    const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight);\n    this.suspendedCtx = this.ctx;\n    this.ctx = scratchCanvas.context;\n    const ctx = this.ctx;\n    ctx.setTransform(...(0,display_utils.getCurrentTransform)(this.suspendedCtx));\n    copyCtxState(this.suspendedCtx, ctx);\n    mirrorContextOperations(ctx, this.suspendedCtx);\n    this.setGState([[\"BM\", \"source-over\"], [\"ca\", 1], [\"CA\", 1]]);\n  }\n  endSMaskMode() {\n    if (!this.inSMaskMode) {\n      throw new Error(\"endSMaskMode called while not in smask mode\");\n    }\n    this.ctx._removeMirroring();\n    copyCtxState(this.ctx, this.suspendedCtx);\n    this.ctx = this.suspendedCtx;\n    this.suspendedCtx = null;\n  }\n  compose(dirtyBox) {\n    if (!this.current.activeSMask) {\n      return;\n    }\n    if (!dirtyBox) {\n      dirtyBox = [0, 0, this.ctx.canvas.width, this.ctx.canvas.height];\n    } else {\n      dirtyBox[0] = Math.floor(dirtyBox[0]);\n      dirtyBox[1] = Math.floor(dirtyBox[1]);\n      dirtyBox[2] = Math.ceil(dirtyBox[2]);\n      dirtyBox[3] = Math.ceil(dirtyBox[3]);\n    }\n    const smask = this.current.activeSMask;\n    const suspendedCtx = this.suspendedCtx;\n    composeSMask(suspendedCtx, smask, this.ctx, dirtyBox);\n    this.ctx.save();\n    this.ctx.setTransform(1, 0, 0, 1, 0, 0);\n    this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);\n    this.ctx.restore();\n  }\n  save() {\n    if (this.inSMaskMode) {\n      copyCtxState(this.ctx, this.suspendedCtx);\n      this.suspendedCtx.save();\n    } else {\n      this.ctx.save();\n    }\n    const old = this.current;\n    this.stateStack.push(old);\n    this.current = old.clone();\n  }\n  restore() {\n    if (this.stateStack.length === 0 && this.inSMaskMode) {\n      this.endSMaskMode();\n    }\n    if (this.stateStack.length !== 0) {\n      this.current = this.stateStack.pop();\n      if (this.inSMaskMode) {\n        this.suspendedCtx.restore();\n        copyCtxState(this.suspendedCtx, this.ctx);\n      } else {\n        this.ctx.restore();\n      }\n      this.checkSMaskState();\n      this.pendingClip = null;\n      this._cachedScaleForStroking[0] = -1;\n      this._cachedGetSinglePixelWidth = null;\n    }\n  }\n  transform(a, b, c, d, e, f) {\n    this.ctx.transform(a, b, c, d, e, f);\n    this._cachedScaleForStroking[0] = -1;\n    this._cachedGetSinglePixelWidth = null;\n  }\n  constructPath(ops, args, minMax) {\n    const ctx = this.ctx;\n    const current = this.current;\n    let x = current.x,\n      y = current.y;\n    let startX, startY;\n    const currentTransform = (0,display_utils.getCurrentTransform)(ctx);\n    const isScalingMatrix = currentTransform[0] === 0 && currentTransform[3] === 0 || currentTransform[1] === 0 && currentTransform[2] === 0;\n    const minMaxForBezier = isScalingMatrix ? minMax.slice(0) : null;\n    for (let i = 0, j = 0, ii = ops.length; i < ii; i++) {\n      switch (ops[i] | 0) {\n        case util.OPS.rectangle:\n          x = args[j++];\n          y = args[j++];\n          const width = args[j++];\n          const height = args[j++];\n          const xw = x + width;\n          const yh = y + height;\n          ctx.moveTo(x, y);\n          if (width === 0 || height === 0) {\n            ctx.lineTo(xw, yh);\n          } else {\n            ctx.lineTo(xw, y);\n            ctx.lineTo(xw, yh);\n            ctx.lineTo(x, yh);\n          }\n          if (!isScalingMatrix) {\n            current.updateRectMinMax(currentTransform, [x, y, xw, yh]);\n          }\n          ctx.closePath();\n          break;\n        case util.OPS.moveTo:\n          x = args[j++];\n          y = args[j++];\n          ctx.moveTo(x, y);\n          if (!isScalingMatrix) {\n            current.updatePathMinMax(currentTransform, x, y);\n          }\n          break;\n        case util.OPS.lineTo:\n          x = args[j++];\n          y = args[j++];\n          ctx.lineTo(x, y);\n          if (!isScalingMatrix) {\n            current.updatePathMinMax(currentTransform, x, y);\n          }\n          break;\n        case util.OPS.curveTo:\n          startX = x;\n          startY = y;\n          x = args[j + 4];\n          y = args[j + 5];\n          ctx.bezierCurveTo(args[j], args[j + 1], args[j + 2], args[j + 3], x, y);\n          current.updateCurvePathMinMax(currentTransform, startX, startY, args[j], args[j + 1], args[j + 2], args[j + 3], x, y, minMaxForBezier);\n          j += 6;\n          break;\n        case util.OPS.curveTo2:\n          startX = x;\n          startY = y;\n          ctx.bezierCurveTo(x, y, args[j], args[j + 1], args[j + 2], args[j + 3]);\n          current.updateCurvePathMinMax(currentTransform, startX, startY, x, y, args[j], args[j + 1], args[j + 2], args[j + 3], minMaxForBezier);\n          x = args[j + 2];\n          y = args[j + 3];\n          j += 4;\n          break;\n        case util.OPS.curveTo3:\n          startX = x;\n          startY = y;\n          x = args[j + 2];\n          y = args[j + 3];\n          ctx.bezierCurveTo(args[j], args[j + 1], x, y, x, y);\n          current.updateCurvePathMinMax(currentTransform, startX, startY, args[j], args[j + 1], x, y, x, y, minMaxForBezier);\n          j += 4;\n          break;\n        case util.OPS.closePath:\n          ctx.closePath();\n          break;\n      }\n    }\n    if (isScalingMatrix) {\n      current.updateScalingPathMinMax(currentTransform, minMaxForBezier);\n    }\n    current.setCurrentPoint(x, y);\n  }\n  closePath() {\n    this.ctx.closePath();\n  }\n  stroke(consumePath = true) {\n    const ctx = this.ctx;\n    const strokeColor = this.current.strokeColor;\n    ctx.globalAlpha = this.current.strokeAlpha;\n    if (this.contentVisible) {\n      if (typeof strokeColor === \"object\" && strokeColor?.getPattern) {\n        ctx.save();\n        ctx.strokeStyle = strokeColor.getPattern(ctx, this, (0,display_utils.getCurrentTransformInverse)(ctx), PathType.STROKE);\n        this.rescaleAndStroke(false);\n        ctx.restore();\n      } else {\n        this.rescaleAndStroke(true);\n      }\n    }\n    if (consumePath) {\n      this.consumePath(this.current.getClippedPathBoundingBox());\n    }\n    ctx.globalAlpha = this.current.fillAlpha;\n  }\n  closeStroke() {\n    this.closePath();\n    this.stroke();\n  }\n  fill(consumePath = true) {\n    const ctx = this.ctx;\n    const fillColor = this.current.fillColor;\n    const isPatternFill = this.current.patternFill;\n    let needRestore = false;\n    if (isPatternFill) {\n      ctx.save();\n      ctx.fillStyle = fillColor.getPattern(ctx, this, (0,display_utils.getCurrentTransformInverse)(ctx), PathType.FILL);\n      needRestore = true;\n    }\n    const intersect = this.current.getClippedPathBoundingBox();\n    if (this.contentVisible && intersect !== null) {\n      if (this.pendingEOFill) {\n        ctx.fill(\"evenodd\");\n        this.pendingEOFill = false;\n      } else {\n        ctx.fill();\n      }\n    }\n    if (needRestore) {\n      ctx.restore();\n    }\n    if (consumePath) {\n      this.consumePath(intersect);\n    }\n  }\n  eoFill() {\n    this.pendingEOFill = true;\n    this.fill();\n  }\n  fillStroke() {\n    this.fill(false);\n    this.stroke(false);\n    this.consumePath();\n  }\n  eoFillStroke() {\n    this.pendingEOFill = true;\n    this.fillStroke();\n  }\n  closeFillStroke() {\n    this.closePath();\n    this.fillStroke();\n  }\n  closeEOFillStroke() {\n    this.pendingEOFill = true;\n    this.closePath();\n    this.fillStroke();\n  }\n  endPath() {\n    this.consumePath();\n  }\n  clip() {\n    this.pendingClip = NORMAL_CLIP;\n  }\n  eoClip() {\n    this.pendingClip = EO_CLIP;\n  }\n  beginText() {\n    this.current.textMatrix = util.IDENTITY_MATRIX;\n    this.current.textMatrixScale = 1;\n    this.current.x = this.current.lineX = 0;\n    this.current.y = this.current.lineY = 0;\n  }\n  endText() {\n    const paths = this.pendingTextPaths;\n    const ctx = this.ctx;\n    if (paths === undefined) {\n      ctx.beginPath();\n      return;\n    }\n    ctx.save();\n    ctx.beginPath();\n    for (const path of paths) {\n      ctx.setTransform(...path.transform);\n      ctx.translate(path.x, path.y);\n      path.addToPath(ctx, path.fontSize);\n    }\n    ctx.restore();\n    ctx.clip();\n    ctx.beginPath();\n    delete this.pendingTextPaths;\n  }\n  setCharSpacing(spacing) {\n    this.current.charSpacing = spacing;\n  }\n  setWordSpacing(spacing) {\n    this.current.wordSpacing = spacing;\n  }\n  setHScale(scale) {\n    this.current.textHScale = scale / 100;\n  }\n  setLeading(leading) {\n    this.current.leading = -leading;\n  }\n  setFont(fontRefName, size) {\n    const fontObj = this.commonObjs.get(fontRefName);\n    const current = this.current;\n    if (!fontObj) {\n      throw new Error(`Can't find font for ${fontRefName}`);\n    }\n    current.fontMatrix = fontObj.fontMatrix || util.FONT_IDENTITY_MATRIX;\n    if (current.fontMatrix[0] === 0 || current.fontMatrix[3] === 0) {\n      (0,util.warn)(\"Invalid font matrix for font \" + fontRefName);\n    }\n    if (size < 0) {\n      size = -size;\n      current.fontDirection = -1;\n    } else {\n      current.fontDirection = 1;\n    }\n    this.current.font = fontObj;\n    this.current.fontSize = size;\n    if (fontObj.isType3Font) {\n      return;\n    }\n    const name = fontObj.loadedName || \"sans-serif\";\n    const typeface = fontObj.systemFontInfo?.css || `\"${name}\", ${fontObj.fallbackName}`;\n    let bold = \"normal\";\n    if (fontObj.black) {\n      bold = \"900\";\n    } else if (fontObj.bold) {\n      bold = \"bold\";\n    }\n    const italic = fontObj.italic ? \"italic\" : \"normal\";\n    let browserFontSize = size;\n    if (size < MIN_FONT_SIZE) {\n      browserFontSize = MIN_FONT_SIZE;\n    } else if (size > MAX_FONT_SIZE) {\n      browserFontSize = MAX_FONT_SIZE;\n    }\n    this.current.fontSizeScale = size / browserFontSize;\n    this.ctx.font = `${italic} ${bold} ${browserFontSize}px ${typeface}`;\n  }\n  setTextRenderingMode(mode) {\n    this.current.textRenderingMode = mode;\n  }\n  setTextRise(rise) {\n    this.current.textRise = rise;\n  }\n  moveText(x, y) {\n    this.current.x = this.current.lineX += x;\n    this.current.y = this.current.lineY += y;\n  }\n  setLeadingMoveText(x, y) {\n    this.setLeading(-y);\n    this.moveText(x, y);\n  }\n  setTextMatrix(a, b, c, d, e, f) {\n    this.current.textMatrix = [a, b, c, d, e, f];\n    this.current.textMatrixScale = Math.hypot(a, b);\n    this.current.x = this.current.lineX = 0;\n    this.current.y = this.current.lineY = 0;\n  }\n  nextLine() {\n    this.moveText(0, this.current.leading);\n  }\n  paintChar(character, x, y, patternTransform) {\n    const ctx = this.ctx;\n    const current = this.current;\n    const font = current.font;\n    const textRenderingMode = current.textRenderingMode;\n    const fontSize = current.fontSize / current.fontSizeScale;\n    const fillStrokeMode = textRenderingMode & util.TextRenderingMode.FILL_STROKE_MASK;\n    const isAddToPathSet = !!(textRenderingMode & util.TextRenderingMode.ADD_TO_PATH_FLAG);\n    const patternFill = current.patternFill && !font.missingFile;\n    let addToPath;\n    if (font.disableFontFace || isAddToPathSet || patternFill) {\n      addToPath = font.getPathGenerator(this.commonObjs, character);\n    }\n    if (font.disableFontFace || patternFill) {\n      ctx.save();\n      ctx.translate(x, y);\n      ctx.beginPath();\n      addToPath(ctx, fontSize);\n      if (patternTransform) {\n        ctx.setTransform(...patternTransform);\n      }\n      if (fillStrokeMode === util.TextRenderingMode.FILL || fillStrokeMode === util.TextRenderingMode.FILL_STROKE) {\n        ctx.fill();\n      }\n      if (fillStrokeMode === util.TextRenderingMode.STROKE || fillStrokeMode === util.TextRenderingMode.FILL_STROKE) {\n        ctx.stroke();\n      }\n      ctx.restore();\n    } else {\n      if (fillStrokeMode === util.TextRenderingMode.FILL || fillStrokeMode === util.TextRenderingMode.FILL_STROKE) {\n        ctx.fillText(character, x, y);\n      }\n      if (fillStrokeMode === util.TextRenderingMode.STROKE || fillStrokeMode === util.TextRenderingMode.FILL_STROKE) {\n        ctx.strokeText(character, x, y);\n      }\n    }\n    if (isAddToPathSet) {\n      const paths = this.pendingTextPaths ||= [];\n      paths.push({\n        transform: (0,display_utils.getCurrentTransform)(ctx),\n        x,\n        y,\n        fontSize,\n        addToPath\n      });\n    }\n  }\n  get isFontSubpixelAAEnabled() {\n    const {\n      context: ctx\n    } = this.cachedCanvases.getCanvas(\"isFontSubpixelAAEnabled\", 10, 10);\n    ctx.scale(1.5, 1);\n    ctx.fillText(\"I\", 0, 10);\n    const data = ctx.getImageData(0, 0, 10, 10).data;\n    let enabled = false;\n    for (let i = 3; i < data.length; i += 4) {\n      if (data[i] > 0 && data[i] < 255) {\n        enabled = true;\n        break;\n      }\n    }\n    return (0,util.shadow)(this, \"isFontSubpixelAAEnabled\", enabled);\n  }\n  showText(glyphs) {\n    const current = this.current;\n    const font = current.font;\n    if (font.isType3Font) {\n      return this.showType3Text(glyphs);\n    }\n    const fontSize = current.fontSize;\n    if (fontSize === 0) {\n      return undefined;\n    }\n    const ctx = this.ctx;\n    const fontSizeScale = current.fontSizeScale;\n    const charSpacing = current.charSpacing;\n    const wordSpacing = current.wordSpacing;\n    const fontDirection = current.fontDirection;\n    const textHScale = current.textHScale * fontDirection;\n    const glyphsLength = glyphs.length;\n    const vertical = font.vertical;\n    const spacingDir = vertical ? 1 : -1;\n    const defaultVMetrics = font.defaultVMetrics;\n    const widthAdvanceScale = fontSize * current.fontMatrix[0];\n    const simpleFillText = current.textRenderingMode === util.TextRenderingMode.FILL && !font.disableFontFace && !current.patternFill;\n    ctx.save();\n    ctx.transform(...current.textMatrix);\n    ctx.translate(current.x, current.y + current.textRise);\n    if (fontDirection > 0) {\n      ctx.scale(textHScale, -1);\n    } else {\n      ctx.scale(textHScale, 1);\n    }\n    let patternTransform;\n    if (current.patternFill) {\n      ctx.save();\n      const pattern = current.fillColor.getPattern(ctx, this, (0,display_utils.getCurrentTransformInverse)(ctx), PathType.FILL);\n      patternTransform = (0,display_utils.getCurrentTransform)(ctx);\n      ctx.restore();\n      ctx.fillStyle = pattern;\n    }\n    let lineWidth = current.lineWidth;\n    const scale = current.textMatrixScale;\n    if (scale === 0 || lineWidth === 0) {\n      const fillStrokeMode = current.textRenderingMode & util.TextRenderingMode.FILL_STROKE_MASK;\n      if (fillStrokeMode === util.TextRenderingMode.STROKE || fillStrokeMode === util.TextRenderingMode.FILL_STROKE) {\n        lineWidth = this.getSinglePixelWidth();\n      }\n    } else {\n      lineWidth /= scale;\n    }\n    if (fontSizeScale !== 1.0) {\n      ctx.scale(fontSizeScale, fontSizeScale);\n      lineWidth /= fontSizeScale;\n    }\n    ctx.lineWidth = lineWidth;\n    if (font.isInvalidPDFjsFont) {\n      const chars = [];\n      let width = 0;\n      for (const glyph of glyphs) {\n        chars.push(glyph.unicode);\n        width += glyph.width;\n      }\n      ctx.fillText(chars.join(\"\"), 0, 0);\n      current.x += width * widthAdvanceScale * textHScale;\n      ctx.restore();\n      this.compose();\n      return undefined;\n    }\n    let x = 0,\n      i;\n    for (i = 0; i < glyphsLength; ++i) {\n      const glyph = glyphs[i];\n      if (typeof glyph === \"number\") {\n        x += spacingDir * glyph * fontSize / 1000;\n        continue;\n      }\n      let restoreNeeded = false;\n      const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing;\n      const character = glyph.fontChar;\n      const accent = glyph.accent;\n      let scaledX, scaledY;\n      let width = glyph.width;\n      if (vertical) {\n        const vmetric = glyph.vmetric || defaultVMetrics;\n        const vx = -(glyph.vmetric ? vmetric[1] : width * 0.5) * widthAdvanceScale;\n        const vy = vmetric[2] * widthAdvanceScale;\n        width = vmetric ? -vmetric[0] : width;\n        scaledX = vx / fontSizeScale;\n        scaledY = (x + vy) / fontSizeScale;\n      } else {\n        scaledX = x / fontSizeScale;\n        scaledY = 0;\n      }\n      if (font.remeasure && width > 0) {\n        const measuredWidth = ctx.measureText(character).width * 1000 / fontSize * fontSizeScale;\n        if (width < measuredWidth && this.isFontSubpixelAAEnabled) {\n          const characterScaleX = width / measuredWidth;\n          restoreNeeded = true;\n          ctx.save();\n          ctx.scale(characterScaleX, 1);\n          scaledX /= characterScaleX;\n        } else if (width !== measuredWidth) {\n          scaledX += (width - measuredWidth) / 2000 * fontSize / fontSizeScale;\n        }\n      }\n      if (this.contentVisible && (glyph.isInFont || font.missingFile)) {\n        if (simpleFillText && !accent) {\n          ctx.fillText(character, scaledX, scaledY);\n        } else {\n          this.paintChar(character, scaledX, scaledY, patternTransform);\n          if (accent) {\n            const scaledAccentX = scaledX + fontSize * accent.offset.x / fontSizeScale;\n            const scaledAccentY = scaledY - fontSize * accent.offset.y / fontSizeScale;\n            this.paintChar(accent.fontChar, scaledAccentX, scaledAccentY, patternTransform);\n          }\n        }\n      }\n      const charWidth = vertical ? width * widthAdvanceScale - spacing * fontDirection : width * widthAdvanceScale + spacing * fontDirection;\n      x += charWidth;\n      if (restoreNeeded) {\n        ctx.restore();\n      }\n    }\n    if (vertical) {\n      current.y -= x;\n    } else {\n      current.x += x * textHScale;\n    }\n    ctx.restore();\n    this.compose();\n    return undefined;\n  }\n  showType3Text(glyphs) {\n    const ctx = this.ctx;\n    const current = this.current;\n    const font = current.font;\n    const fontSize = current.fontSize;\n    const fontDirection = current.fontDirection;\n    const spacingDir = font.vertical ? 1 : -1;\n    const charSpacing = current.charSpacing;\n    const wordSpacing = current.wordSpacing;\n    const textHScale = current.textHScale * fontDirection;\n    const fontMatrix = current.fontMatrix || util.FONT_IDENTITY_MATRIX;\n    const glyphsLength = glyphs.length;\n    const isTextInvisible = current.textRenderingMode === util.TextRenderingMode.INVISIBLE;\n    let i, glyph, width, spacingLength;\n    if (isTextInvisible || fontSize === 0) {\n      return;\n    }\n    this._cachedScaleForStroking[0] = -1;\n    this._cachedGetSinglePixelWidth = null;\n    ctx.save();\n    ctx.transform(...current.textMatrix);\n    ctx.translate(current.x, current.y);\n    ctx.scale(textHScale, fontDirection);\n    for (i = 0; i < glyphsLength; ++i) {\n      glyph = glyphs[i];\n      if (typeof glyph === \"number\") {\n        spacingLength = spacingDir * glyph * fontSize / 1000;\n        this.ctx.translate(spacingLength, 0);\n        current.x += spacingLength * textHScale;\n        continue;\n      }\n      const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing;\n      const operatorList = font.charProcOperatorList[glyph.operatorListId];\n      if (!operatorList) {\n        (0,util.warn)(`Type3 character \"${glyph.operatorListId}\" is not available.`);\n        continue;\n      }\n      if (this.contentVisible) {\n        this.processingType3 = glyph;\n        this.save();\n        ctx.scale(fontSize, fontSize);\n        ctx.transform(...fontMatrix);\n        this.executeOperatorList(operatorList);\n        this.restore();\n      }\n      const transformed = util.Util.applyTransform([glyph.width, 0], fontMatrix);\n      width = transformed[0] * fontSize + spacing;\n      ctx.translate(width, 0);\n      current.x += width * textHScale;\n    }\n    ctx.restore();\n    this.processingType3 = null;\n  }\n  setCharWidth(xWidth, yWidth) {}\n  setCharWidthAndBounds(xWidth, yWidth, llx, lly, urx, ury) {\n    this.ctx.rect(llx, lly, urx - llx, ury - lly);\n    this.ctx.clip();\n    this.endPath();\n  }\n  getColorN_Pattern(IR) {\n    let pattern;\n    if (IR[0] === \"TilingPattern\") {\n      const color = IR[1];\n      const baseTransform = this.baseTransform || (0,display_utils.getCurrentTransform)(this.ctx);\n      const canvasGraphicsFactory = {\n        createCanvasGraphics: ctx => new CanvasGraphics(ctx, this.commonObjs, this.objs, this.canvasFactory, this.filterFactory, {\n          optionalContentConfig: this.optionalContentConfig,\n          markedContentStack: this.markedContentStack\n        })\n      };\n      pattern = new TilingPattern(IR, color, this.ctx, canvasGraphicsFactory, baseTransform);\n    } else {\n      pattern = this._getPattern(IR[1], IR[2]);\n    }\n    return pattern;\n  }\n  setStrokeColorN() {\n    this.current.strokeColor = this.getColorN_Pattern(arguments);\n  }\n  setFillColorN() {\n    this.current.fillColor = this.getColorN_Pattern(arguments);\n    this.current.patternFill = true;\n  }\n  setStrokeRGBColor(r, g, b) {\n    const color = util.Util.makeHexColor(r, g, b);\n    this.ctx.strokeStyle = color;\n    this.current.strokeColor = color;\n  }\n  setFillRGBColor(r, g, b) {\n    const color = util.Util.makeHexColor(r, g, b);\n    this.ctx.fillStyle = color;\n    this.current.fillColor = color;\n    this.current.patternFill = false;\n  }\n  _getPattern(objId, matrix = null) {\n    let pattern;\n    if (this.cachedPatterns.has(objId)) {\n      pattern = this.cachedPatterns.get(objId);\n    } else {\n      pattern = getShadingPattern(this.getObject(objId));\n      this.cachedPatterns.set(objId, pattern);\n    }\n    if (matrix) {\n      pattern.matrix = matrix;\n    }\n    return pattern;\n  }\n  shadingFill(objId) {\n    if (!this.contentVisible) {\n      return;\n    }\n    const ctx = this.ctx;\n    this.save();\n    const pattern = this._getPattern(objId);\n    ctx.fillStyle = pattern.getPattern(ctx, this, (0,display_utils.getCurrentTransformInverse)(ctx), PathType.SHADING);\n    const inv = (0,display_utils.getCurrentTransformInverse)(ctx);\n    if (inv) {\n      const {\n        width,\n        height\n      } = ctx.canvas;\n      const [x0, y0, x1, y1] = util.Util.getAxialAlignedBoundingBox([0, 0, width, height], inv);\n      this.ctx.fillRect(x0, y0, x1 - x0, y1 - y0);\n    } else {\n      this.ctx.fillRect(-1e10, -1e10, 2e10, 2e10);\n    }\n    this.compose(this.current.getClippedPathBoundingBox());\n    this.restore();\n  }\n  beginInlineImage() {\n    (0,util.unreachable)(\"Should not call beginInlineImage\");\n  }\n  beginImageData() {\n    (0,util.unreachable)(\"Should not call beginImageData\");\n  }\n  paintFormXObjectBegin(matrix, bbox) {\n    if (!this.contentVisible) {\n      return;\n    }\n    this.save();\n    this.baseTransformStack.push(this.baseTransform);\n    if (Array.isArray(matrix) && matrix.length === 6) {\n      this.transform(...matrix);\n    }\n    this.baseTransform = (0,display_utils.getCurrentTransform)(this.ctx);\n    if (bbox) {\n      const width = bbox[2] - bbox[0];\n      const height = bbox[3] - bbox[1];\n      this.ctx.rect(bbox[0], bbox[1], width, height);\n      this.current.updateRectMinMax((0,display_utils.getCurrentTransform)(this.ctx), bbox);\n      this.clip();\n      this.endPath();\n    }\n  }\n  paintFormXObjectEnd() {\n    if (!this.contentVisible) {\n      return;\n    }\n    this.restore();\n    this.baseTransform = this.baseTransformStack.pop();\n  }\n  beginGroup(group) {\n    if (!this.contentVisible) {\n      return;\n    }\n    this.save();\n    if (this.inSMaskMode) {\n      this.endSMaskMode();\n      this.current.activeSMask = null;\n    }\n    const currentCtx = this.ctx;\n    if (!group.isolated) {\n      (0,util.info)(\"TODO: Support non-isolated groups.\");\n    }\n    if (group.knockout) {\n      (0,util.warn)(\"Knockout groups not supported.\");\n    }\n    const currentTransform = (0,display_utils.getCurrentTransform)(currentCtx);\n    if (group.matrix) {\n      currentCtx.transform(...group.matrix);\n    }\n    if (!group.bbox) {\n      throw new Error(\"Bounding box is required.\");\n    }\n    let bounds = util.Util.getAxialAlignedBoundingBox(group.bbox, (0,display_utils.getCurrentTransform)(currentCtx));\n    const canvasBounds = [0, 0, currentCtx.canvas.width, currentCtx.canvas.height];\n    bounds = util.Util.intersect(bounds, canvasBounds) || [0, 0, 0, 0];\n    const offsetX = Math.floor(bounds[0]);\n    const offsetY = Math.floor(bounds[1]);\n    let drawnWidth = Math.max(Math.ceil(bounds[2]) - offsetX, 1);\n    let drawnHeight = Math.max(Math.ceil(bounds[3]) - offsetY, 1);\n    let scaleX = 1,\n      scaleY = 1;\n    if (drawnWidth > MAX_GROUP_SIZE) {\n      scaleX = drawnWidth / MAX_GROUP_SIZE;\n      drawnWidth = MAX_GROUP_SIZE;\n    }\n    if (drawnHeight > MAX_GROUP_SIZE) {\n      scaleY = drawnHeight / MAX_GROUP_SIZE;\n      drawnHeight = MAX_GROUP_SIZE;\n    }\n    this.current.startNewPathAndClipBox([0, 0, drawnWidth, drawnHeight]);\n    let cacheId = \"groupAt\" + this.groupLevel;\n    if (group.smask) {\n      cacheId += \"_smask_\" + this.smaskCounter++ % 2;\n    }\n    const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight);\n    const groupCtx = scratchCanvas.context;\n    groupCtx.scale(1 / scaleX, 1 / scaleY);\n    groupCtx.translate(-offsetX, -offsetY);\n    groupCtx.transform(...currentTransform);\n    if (group.smask) {\n      this.smaskStack.push({\n        canvas: scratchCanvas.canvas,\n        context: groupCtx,\n        offsetX,\n        offsetY,\n        scaleX,\n        scaleY,\n        subtype: group.smask.subtype,\n        backdrop: group.smask.backdrop,\n        transferMap: group.smask.transferMap || null,\n        startTransformInverse: null\n      });\n    } else {\n      currentCtx.setTransform(1, 0, 0, 1, 0, 0);\n      currentCtx.translate(offsetX, offsetY);\n      currentCtx.scale(scaleX, scaleY);\n      currentCtx.save();\n    }\n    copyCtxState(currentCtx, groupCtx);\n    this.ctx = groupCtx;\n    this.setGState([[\"BM\", \"source-over\"], [\"ca\", 1], [\"CA\", 1]]);\n    this.groupStack.push(currentCtx);\n    this.groupLevel++;\n  }\n  endGroup(group) {\n    if (!this.contentVisible) {\n      return;\n    }\n    this.groupLevel--;\n    const groupCtx = this.ctx;\n    const ctx = this.groupStack.pop();\n    this.ctx = ctx;\n    this.ctx.imageSmoothingEnabled = false;\n    if (group.smask) {\n      this.tempSMask = this.smaskStack.pop();\n      this.restore();\n    } else {\n      this.ctx.restore();\n      const currentMtx = (0,display_utils.getCurrentTransform)(this.ctx);\n      this.restore();\n      this.ctx.save();\n      this.ctx.setTransform(...currentMtx);\n      const dirtyBox = util.Util.getAxialAlignedBoundingBox([0, 0, groupCtx.canvas.width, groupCtx.canvas.height], currentMtx);\n      this.ctx.drawImage(groupCtx.canvas, 0, 0);\n      this.ctx.restore();\n      this.compose(dirtyBox);\n    }\n  }\n  beginAnnotation(id, rect, transform, matrix, hasOwnCanvas) {\n    this.#restoreInitialState();\n    resetCtxToDefault(this.ctx);\n    this.ctx.save();\n    this.save();\n    if (this.baseTransform) {\n      this.ctx.setTransform(...this.baseTransform);\n    }\n    if (Array.isArray(rect) && rect.length === 4) {\n      const width = rect[2] - rect[0];\n      const height = rect[3] - rect[1];\n      if (hasOwnCanvas && this.annotationCanvasMap) {\n        transform = transform.slice();\n        transform[4] -= rect[0];\n        transform[5] -= rect[1];\n        rect = rect.slice();\n        rect[0] = rect[1] = 0;\n        rect[2] = width;\n        rect[3] = height;\n        const [scaleX, scaleY] = util.Util.singularValueDecompose2dScale((0,display_utils.getCurrentTransform)(this.ctx));\n        const {\n          viewportScale\n        } = this;\n        const canvasWidth = Math.ceil(width * this.outputScaleX * viewportScale);\n        const canvasHeight = Math.ceil(height * this.outputScaleY * viewportScale);\n        this.annotationCanvas = this.canvasFactory.create(canvasWidth, canvasHeight);\n        const {\n          canvas,\n          context\n        } = this.annotationCanvas;\n        this.annotationCanvasMap.set(id, canvas);\n        this.annotationCanvas.savedCtx = this.ctx;\n        this.ctx = context;\n        this.ctx.save();\n        this.ctx.setTransform(scaleX, 0, 0, -scaleY, 0, height * scaleY);\n        resetCtxToDefault(this.ctx);\n      } else {\n        resetCtxToDefault(this.ctx);\n        this.ctx.rect(rect[0], rect[1], width, height);\n        this.ctx.clip();\n        this.endPath();\n      }\n    }\n    this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height);\n    this.transform(...transform);\n    this.transform(...matrix);\n  }\n  endAnnotation() {\n    if (this.annotationCanvas) {\n      this.ctx.restore();\n      this.#drawFilter();\n      this.ctx = this.annotationCanvas.savedCtx;\n      delete this.annotationCanvas.savedCtx;\n      delete this.annotationCanvas;\n    }\n  }\n  paintImageMaskXObject(img) {\n    if (!this.contentVisible) {\n      return;\n    }\n    const count = img.count;\n    img = this.getObject(img.data, img);\n    img.count = count;\n    const ctx = this.ctx;\n    const glyph = this.processingType3;\n    if (glyph) {\n      if (glyph.compiled === undefined) {\n        glyph.compiled = compileType3Glyph(img);\n      }\n      if (glyph.compiled) {\n        glyph.compiled(ctx);\n        return;\n      }\n    }\n    const mask = this._createMaskCanvas(img);\n    const maskCanvas = mask.canvas;\n    ctx.save();\n    ctx.setTransform(1, 0, 0, 1, 0, 0);\n    ctx.drawImage(maskCanvas, mask.offsetX, mask.offsetY);\n    ctx.restore();\n    this.compose();\n  }\n  paintImageMaskXObjectRepeat(img, scaleX, skewX = 0, skewY = 0, scaleY, positions) {\n    if (!this.contentVisible) {\n      return;\n    }\n    img = this.getObject(img.data, img);\n    const ctx = this.ctx;\n    ctx.save();\n    const currentTransform = (0,display_utils.getCurrentTransform)(ctx);\n    ctx.transform(scaleX, skewX, skewY, scaleY, 0, 0);\n    const mask = this._createMaskCanvas(img);\n    ctx.setTransform(1, 0, 0, 1, mask.offsetX - currentTransform[4], mask.offsetY - currentTransform[5]);\n    for (let i = 0, ii = positions.length; i < ii; i += 2) {\n      const trans = util.Util.transform(currentTransform, [scaleX, skewX, skewY, scaleY, positions[i], positions[i + 1]]);\n      const [x, y] = util.Util.applyTransform([0, 0], trans);\n      ctx.drawImage(mask.canvas, x, y);\n    }\n    ctx.restore();\n    this.compose();\n  }\n  paintImageMaskXObjectGroup(images) {\n    if (!this.contentVisible) {\n      return;\n    }\n    const ctx = this.ctx;\n    const fillColor = this.current.fillColor;\n    const isPatternFill = this.current.patternFill;\n    for (const image of images) {\n      const {\n        data,\n        width,\n        height,\n        transform\n      } = image;\n      const maskCanvas = this.cachedCanvases.getCanvas(\"maskCanvas\", width, height);\n      const maskCtx = maskCanvas.context;\n      maskCtx.save();\n      const img = this.getObject(data, image);\n      putBinaryImageMask(maskCtx, img);\n      maskCtx.globalCompositeOperation = \"source-in\";\n      maskCtx.fillStyle = isPatternFill ? fillColor.getPattern(maskCtx, this, (0,display_utils.getCurrentTransformInverse)(ctx), PathType.FILL) : fillColor;\n      maskCtx.fillRect(0, 0, width, height);\n      maskCtx.restore();\n      ctx.save();\n      ctx.transform(...transform);\n      ctx.scale(1, -1);\n      drawImageAtIntegerCoords(ctx, maskCanvas.canvas, 0, 0, width, height, 0, -1, 1, 1);\n      ctx.restore();\n    }\n    this.compose();\n  }\n  paintImageXObject(objId) {\n    if (!this.contentVisible) {\n      return;\n    }\n    const imgData = this.getObject(objId);\n    if (!imgData) {\n      (0,util.warn)(\"Dependent image isn't ready yet\");\n      return;\n    }\n    this.paintInlineImageXObject(imgData);\n  }\n  paintImageXObjectRepeat(objId, scaleX, scaleY, positions) {\n    if (!this.contentVisible) {\n      return;\n    }\n    const imgData = this.getObject(objId);\n    if (!imgData) {\n      (0,util.warn)(\"Dependent image isn't ready yet\");\n      return;\n    }\n    const width = imgData.width;\n    const height = imgData.height;\n    const map = [];\n    for (let i = 0, ii = positions.length; i < ii; i += 2) {\n      map.push({\n        transform: [scaleX, 0, 0, scaleY, positions[i], positions[i + 1]],\n        x: 0,\n        y: 0,\n        w: width,\n        h: height\n      });\n    }\n    this.paintInlineImageXObjectGroup(imgData, map);\n  }\n  applyTransferMapsToCanvas(ctx) {\n    if (this.current.transferMaps !== \"none\") {\n      ctx.filter = this.current.transferMaps;\n      ctx.drawImage(ctx.canvas, 0, 0);\n      ctx.filter = \"none\";\n    }\n    return ctx.canvas;\n  }\n  applyTransferMapsToBitmap(imgData) {\n    if (this.current.transferMaps === \"none\") {\n      return imgData.bitmap;\n    }\n    const {\n      bitmap,\n      width,\n      height\n    } = imgData;\n    const tmpCanvas = this.cachedCanvases.getCanvas(\"inlineImage\", width, height);\n    const tmpCtx = tmpCanvas.context;\n    tmpCtx.filter = this.current.transferMaps;\n    tmpCtx.drawImage(bitmap, 0, 0);\n    tmpCtx.filter = \"none\";\n    return tmpCanvas.canvas;\n  }\n  paintInlineImageXObject(imgData) {\n    if (!this.contentVisible) {\n      return;\n    }\n    const width = imgData.width;\n    const height = imgData.height;\n    const ctx = this.ctx;\n    this.save();\n    if (!util.isNodeJS) {\n      const {\n        filter\n      } = ctx;\n      if (filter !== \"none\" && filter !== \"\") {\n        ctx.filter = \"none\";\n      }\n    }\n    ctx.scale(1 / width, -1 / height);\n    let imgToPaint;\n    if (imgData.bitmap) {\n      imgToPaint = this.applyTransferMapsToBitmap(imgData);\n    } else if (typeof HTMLElement === \"function\" && imgData instanceof HTMLElement || !imgData.data) {\n      imgToPaint = imgData;\n    } else {\n      const tmpCanvas = this.cachedCanvases.getCanvas(\"inlineImage\", width, height);\n      const tmpCtx = tmpCanvas.context;\n      putBinaryImageData(tmpCtx, imgData);\n      imgToPaint = this.applyTransferMapsToCanvas(tmpCtx);\n    }\n    const scaled = this._scaleImage(imgToPaint, (0,display_utils.getCurrentTransformInverse)(ctx));\n    ctx.imageSmoothingEnabled = getImageSmoothingEnabled((0,display_utils.getCurrentTransform)(ctx), imgData.interpolate);\n    drawImageAtIntegerCoords(ctx, scaled.img, 0, 0, scaled.paintWidth, scaled.paintHeight, 0, -height, width, height);\n    this.compose();\n    this.restore();\n  }\n  paintInlineImageXObjectGroup(imgData, map) {\n    if (!this.contentVisible) {\n      return;\n    }\n    const ctx = this.ctx;\n    let imgToPaint;\n    if (imgData.bitmap) {\n      imgToPaint = imgData.bitmap;\n    } else {\n      const w = imgData.width;\n      const h = imgData.height;\n      const tmpCanvas = this.cachedCanvases.getCanvas(\"inlineImage\", w, h);\n      const tmpCtx = tmpCanvas.context;\n      putBinaryImageData(tmpCtx, imgData);\n      imgToPaint = this.applyTransferMapsToCanvas(tmpCtx);\n    }\n    for (const entry of map) {\n      ctx.save();\n      ctx.transform(...entry.transform);\n      ctx.scale(1, -1);\n      drawImageAtIntegerCoords(ctx, imgToPaint, entry.x, entry.y, entry.w, entry.h, 0, -1, 1, 1);\n      ctx.restore();\n    }\n    this.compose();\n  }\n  paintSolidColorImageMask() {\n    if (!this.contentVisible) {\n      return;\n    }\n    this.ctx.fillRect(0, 0, 1, 1);\n    this.compose();\n  }\n  markPoint(tag) {}\n  markPointProps(tag, properties) {}\n  beginMarkedContent(tag) {\n    this.markedContentStack.push({\n      visible: true\n    });\n  }\n  beginMarkedContentProps(tag, properties) {\n    if (tag === \"OC\") {\n      this.markedContentStack.push({\n        visible: this.optionalContentConfig.isVisible(properties)\n      });\n    } else {\n      this.markedContentStack.push({\n        visible: true\n      });\n    }\n    this.contentVisible = this.isContentVisible();\n  }\n  endMarkedContent() {\n    this.markedContentStack.pop();\n    this.contentVisible = this.isContentVisible();\n  }\n  beginCompat() {}\n  endCompat() {}\n  consumePath(clipBox) {\n    const isEmpty = this.current.isEmptyClip();\n    if (this.pendingClip) {\n      this.current.updateClipFromPath();\n    }\n    if (!this.pendingClip) {\n      this.compose(clipBox);\n    }\n    const ctx = this.ctx;\n    if (this.pendingClip) {\n      if (!isEmpty) {\n        if (this.pendingClip === EO_CLIP) {\n          ctx.clip(\"evenodd\");\n        } else {\n          ctx.clip();\n        }\n      }\n      this.pendingClip = null;\n    }\n    this.current.startNewPathAndClipBox(this.current.clipBox);\n    ctx.beginPath();\n  }\n  getSinglePixelWidth() {\n    if (!this._cachedGetSinglePixelWidth) {\n      const m = (0,display_utils.getCurrentTransform)(this.ctx);\n      if (m[1] === 0 && m[2] === 0) {\n        this._cachedGetSinglePixelWidth = 1 / Math.min(Math.abs(m[0]), Math.abs(m[3]));\n      } else {\n        const absDet = Math.abs(m[0] * m[3] - m[2] * m[1]);\n        const normX = Math.hypot(m[0], m[2]);\n        const normY = Math.hypot(m[1], m[3]);\n        this._cachedGetSinglePixelWidth = Math.max(normX, normY) / absDet;\n      }\n    }\n    return this._cachedGetSinglePixelWidth;\n  }\n  getScaleForStroking() {\n    if (this._cachedScaleForStroking[0] === -1) {\n      const {\n        lineWidth\n      } = this.current;\n      const {\n        a,\n        b,\n        c,\n        d\n      } = this.ctx.getTransform();\n      let scaleX, scaleY;\n      if (b === 0 && c === 0) {\n        const normX = Math.abs(a);\n        const normY = Math.abs(d);\n        if (normX === normY) {\n          if (lineWidth === 0) {\n            scaleX = scaleY = 1 / normX;\n          } else {\n            const scaledLineWidth = normX * lineWidth;\n            scaleX = scaleY = scaledLineWidth < 1 ? 1 / scaledLineWidth : 1;\n          }\n        } else if (lineWidth === 0) {\n          scaleX = 1 / normX;\n          scaleY = 1 / normY;\n        } else {\n          const scaledXLineWidth = normX * lineWidth;\n          const scaledYLineWidth = normY * lineWidth;\n          scaleX = scaledXLineWidth < 1 ? 1 / scaledXLineWidth : 1;\n          scaleY = scaledYLineWidth < 1 ? 1 / scaledYLineWidth : 1;\n        }\n      } else {\n        const absDet = Math.abs(a * d - b * c);\n        const normX = Math.hypot(a, b);\n        const normY = Math.hypot(c, d);\n        if (lineWidth === 0) {\n          scaleX = normY / absDet;\n          scaleY = normX / absDet;\n        } else {\n          const baseArea = lineWidth * absDet;\n          scaleX = normY > baseArea ? normY / baseArea : 1;\n          scaleY = normX > baseArea ? normX / baseArea : 1;\n        }\n      }\n      this._cachedScaleForStroking[0] = scaleX;\n      this._cachedScaleForStroking[1] = scaleY;\n    }\n    return this._cachedScaleForStroking;\n  }\n  rescaleAndStroke(saveRestore) {\n    const {\n      ctx\n    } = this;\n    const {\n      lineWidth\n    } = this.current;\n    const [scaleX, scaleY] = this.getScaleForStroking();\n    ctx.lineWidth = lineWidth || 1;\n    if (scaleX === 1 && scaleY === 1) {\n      ctx.stroke();\n      return;\n    }\n    const dashes = ctx.getLineDash();\n    if (saveRestore) {\n      ctx.save();\n    }\n    ctx.scale(scaleX, scaleY);\n    if (dashes.length > 0) {\n      const scale = Math.max(scaleX, scaleY);\n      ctx.setLineDash(dashes.map(x => x / scale));\n      ctx.lineDashOffset /= scale;\n    }\n    ctx.stroke();\n    if (saveRestore) {\n      ctx.restore();\n    }\n  }\n  isContentVisible() {\n    for (let i = this.markedContentStack.length - 1; i >= 0; i--) {\n      if (!this.markedContentStack[i].visible) {\n        return false;\n      }\n    }\n    return true;\n  }\n}\nfor (const op in util.OPS) {\n  if (CanvasGraphics.prototype[op] !== undefined) {\n    CanvasGraphics.prototype[util.OPS[op]] = CanvasGraphics.prototype[op];\n  }\n}\n\n\n/***/ }),\n\n/***/ 976:\n/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {\n\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n  AnnotationLayer: () => (/* binding */ AnnotationLayer),\n  FreeTextAnnotationElement: () => (/* binding */ FreeTextAnnotationElement),\n  InkAnnotationElement: () => (/* binding */ InkAnnotationElement),\n  StampAnnotationElement: () => (/* binding */ StampAnnotationElement)\n});\n\n// EXTERNAL MODULE: ./src/shared/util.js\nvar util = __webpack_require__(292);\n// EXTERNAL MODULE: ./src/display/display_utils.js\nvar display_utils = __webpack_require__(419);\n// EXTERNAL MODULE: ./src/display/annotation_storage.js\nvar annotation_storage = __webpack_require__(792);\n;// ./src/shared/scripting_utils.js\nfunction makeColorComp(n) {\n  return Math.floor(Math.max(0, Math.min(1, n)) * 255).toString(16).padStart(2, \"0\");\n}\nfunction scaleAndClamp(x) {\n  return Math.max(0, Math.min(255, 255 * x));\n}\nclass ColorConverters {\n  static CMYK_G([c, y, m, k]) {\n    return [\"G\", 1 - Math.min(1, 0.3 * c + 0.59 * m + 0.11 * y + k)];\n  }\n  static G_CMYK([g]) {\n    return [\"CMYK\", 0, 0, 0, 1 - g];\n  }\n  static G_RGB([g]) {\n    return [\"RGB\", g, g, g];\n  }\n  static G_rgb([g]) {\n    g = scaleAndClamp(g);\n    return [g, g, g];\n  }\n  static G_HTML([g]) {\n    const G = makeColorComp(g);\n    return `#${G}${G}${G}`;\n  }\n  static RGB_G([r, g, b]) {\n    return [\"G\", 0.3 * r + 0.59 * g + 0.11 * b];\n  }\n  static RGB_rgb(color) {\n    return color.map(scaleAndClamp);\n  }\n  static RGB_HTML(color) {\n    return `#${color.map(makeColorComp).join(\"\")}`;\n  }\n  static T_HTML() {\n    return \"#00000000\";\n  }\n  static T_rgb() {\n    return [null];\n  }\n  static CMYK_RGB([c, y, m, k]) {\n    return [\"RGB\", 1 - Math.min(1, c + k), 1 - Math.min(1, m + k), 1 - Math.min(1, y + k)];\n  }\n  static CMYK_rgb([c, y, m, k]) {\n    return [scaleAndClamp(1 - Math.min(1, c + k)), scaleAndClamp(1 - Math.min(1, m + k)), scaleAndClamp(1 - Math.min(1, y + k))];\n  }\n  static CMYK_HTML(components) {\n    const rgb = this.CMYK_RGB(components).slice(1);\n    return this.RGB_HTML(rgb);\n  }\n  static RGB_CMYK([r, g, b]) {\n    const c = 1 - r;\n    const m = 1 - g;\n    const y = 1 - b;\n    const k = Math.min(c, m, y);\n    return [\"CMYK\", c, m, y, k];\n  }\n}\n\n// EXTERNAL MODULE: ./src/display/xfa_layer.js\nvar xfa_layer = __webpack_require__(284);\n;// ./src/display/annotation_layer.js\n\n\n\n\n\nconst DEFAULT_TAB_INDEX = 1000;\nconst DEFAULT_FONT_SIZE = 9;\nconst GetElementsByNameSet = new WeakSet();\nfunction getRectDims(rect) {\n  return {\n    width: rect[2] - rect[0],\n    height: rect[3] - rect[1]\n  };\n}\nclass AnnotationElementFactory {\n  static create(parameters) {\n    const subtype = parameters.data.annotationType;\n    switch (subtype) {\n      case util.AnnotationType.LINK:\n        return new LinkAnnotationElement(parameters);\n      case util.AnnotationType.TEXT:\n        return new TextAnnotationElement(parameters);\n      case util.AnnotationType.WIDGET:\n        const fieldType = parameters.data.fieldType;\n        switch (fieldType) {\n          case \"Tx\":\n            return new TextWidgetAnnotationElement(parameters);\n          case \"Btn\":\n            if (parameters.data.radioButton) {\n              return new RadioButtonWidgetAnnotationElement(parameters);\n            } else if (parameters.data.checkBox) {\n              return new CheckboxWidgetAnnotationElement(parameters);\n            }\n            return new PushButtonWidgetAnnotationElement(parameters);\n          case \"Ch\":\n            return new ChoiceWidgetAnnotationElement(parameters);\n          case \"Sig\":\n            return new SignatureWidgetAnnotationElement(parameters);\n        }\n        return new WidgetAnnotationElement(parameters);\n      case util.AnnotationType.POPUP:\n        return new PopupAnnotationElement(parameters);\n      case util.AnnotationType.FREETEXT:\n        return new FreeTextAnnotationElement(parameters);\n      case util.AnnotationType.LINE:\n        return new LineAnnotationElement(parameters);\n      case util.AnnotationType.SQUARE:\n        return new SquareAnnotationElement(parameters);\n      case util.AnnotationType.CIRCLE:\n        return new CircleAnnotationElement(parameters);\n      case util.AnnotationType.POLYLINE:\n        return new PolylineAnnotationElement(parameters);\n      case util.AnnotationType.CARET:\n        return new CaretAnnotationElement(parameters);\n      case util.AnnotationType.INK:\n        return new InkAnnotationElement(parameters);\n      case util.AnnotationType.POLYGON:\n        return new PolygonAnnotationElement(parameters);\n      case util.AnnotationType.HIGHLIGHT:\n        return new HighlightAnnotationElement(parameters);\n      case util.AnnotationType.UNDERLINE:\n        return new UnderlineAnnotationElement(parameters);\n      case util.AnnotationType.SQUIGGLY:\n        return new SquigglyAnnotationElement(parameters);\n      case util.AnnotationType.STRIKEOUT:\n        return new StrikeOutAnnotationElement(parameters);\n      case util.AnnotationType.STAMP:\n        return new StampAnnotationElement(parameters);\n      case util.AnnotationType.FILEATTACHMENT:\n        return new FileAttachmentAnnotationElement(parameters);\n      default:\n        return new AnnotationElement(parameters);\n    }\n  }\n}\nclass AnnotationElement {\n  #hasBorder = false;\n  constructor(parameters, {\n    isRenderable = false,\n    ignoreBorder = false,\n    createQuadrilaterals = false\n  } = {}) {\n    this.isRenderable = isRenderable;\n    this.data = parameters.data;\n    this.layer = parameters.layer;\n    this.linkService = parameters.linkService;\n    this.downloadManager = parameters.downloadManager;\n    this.imageResourcesPath = parameters.imageResourcesPath;\n    this.renderForms = parameters.renderForms;\n    this.svgFactory = parameters.svgFactory;\n    this.annotationStorage = parameters.annotationStorage;\n    this.enableScripting = parameters.enableScripting;\n    this.hasJSActions = parameters.hasJSActions;\n    this._fieldObjects = parameters.fieldObjects;\n    this.parent = parameters.parent;\n    if (isRenderable) {\n      this.container = this._createContainer(ignoreBorder);\n    }\n    if (createQuadrilaterals) {\n      this._createQuadrilaterals();\n    }\n  }\n  static _hasPopupData({\n    titleObj,\n    contentsObj,\n    richText\n  }) {\n    return !!(titleObj?.str || contentsObj?.str || richText?.str);\n  }\n  get hasPopupData() {\n    return AnnotationElement._hasPopupData(this.data);\n  }\n  _createContainer(ignoreBorder) {\n    const {\n      data,\n      parent: {\n        page,\n        viewport\n      }\n    } = this;\n    const container = document.createElement(\"section\");\n    container.setAttribute(\"data-annotation-id\", data.id);\n    if (!(this instanceof WidgetAnnotationElement)) {\n      container.tabIndex = DEFAULT_TAB_INDEX;\n    }\n    container.style.zIndex = this.parent.zIndex++;\n    if (this.data.popupRef) {\n      container.setAttribute(\"aria-haspopup\", \"dialog\");\n    }\n    if (data.noRotate) {\n      container.classList.add(\"norotate\");\n    }\n    const {\n      pageWidth,\n      pageHeight,\n      pageX,\n      pageY\n    } = viewport.rawDims;\n    if (!data.rect || this instanceof PopupAnnotationElement) {\n      const {\n        rotation\n      } = data;\n      if (!data.hasOwnCanvas && rotation !== 0) {\n        this.setRotation(rotation, container);\n      }\n      return container;\n    }\n    const {\n      width,\n      height\n    } = getRectDims(data.rect);\n    const rect = util.Util.normalizeRect([data.rect[0], page.view[3] - data.rect[1] + page.view[1], data.rect[2], page.view[3] - data.rect[3] + page.view[1]]);\n    if (!ignoreBorder && data.borderStyle.width > 0) {\n      container.style.borderWidth = `${data.borderStyle.width}px`;\n      const horizontalRadius = data.borderStyle.horizontalCornerRadius;\n      const verticalRadius = data.borderStyle.verticalCornerRadius;\n      if (horizontalRadius > 0 || verticalRadius > 0) {\n        const radius = `calc(${horizontalRadius}px * var(--scale-factor)) / calc(${verticalRadius}px * var(--scale-factor))`;\n        container.style.borderRadius = radius;\n      } else if (this instanceof RadioButtonWidgetAnnotationElement) {\n        const radius = `calc(${width}px * var(--scale-factor)) / calc(${height}px * var(--scale-factor))`;\n        container.style.borderRadius = radius;\n      }\n      switch (data.borderStyle.style) {\n        case util.AnnotationBorderStyleType.SOLID:\n          container.style.borderStyle = \"solid\";\n          break;\n        case util.AnnotationBorderStyleType.DASHED:\n          container.style.borderStyle = \"dashed\";\n          break;\n        case util.AnnotationBorderStyleType.BEVELED:\n          (0,util.warn)(\"Unimplemented border style: beveled\");\n          break;\n        case util.AnnotationBorderStyleType.INSET:\n          (0,util.warn)(\"Unimplemented border style: inset\");\n          break;\n        case util.AnnotationBorderStyleType.UNDERLINE:\n          container.style.borderBottomStyle = \"solid\";\n          break;\n        default:\n          break;\n      }\n      const borderColor = data.borderColor || null;\n      if (borderColor) {\n        this.#hasBorder = true;\n        container.style.borderColor = util.Util.makeHexColor(borderColor[0] | 0, borderColor[1] | 0, borderColor[2] | 0);\n      } else {\n        container.style.borderWidth = 0;\n      }\n    }\n    container.style.left = `${100 * (rect[0] - pageX) / pageWidth}%`;\n    container.style.top = `${100 * (rect[1] - pageY) / pageHeight}%`;\n    const {\n      rotation\n    } = data;\n    if (data.hasOwnCanvas || rotation === 0) {\n      container.style.width = `${100 * width / pageWidth}%`;\n      container.style.height = `${100 * height / pageHeight}%`;\n    } else {\n      this.setRotation(rotation, container);\n    }\n    return container;\n  }\n  setRotation(angle, container = this.container) {\n    if (!this.data.rect) {\n      return;\n    }\n    const {\n      pageWidth,\n      pageHeight\n    } = this.parent.viewport.rawDims;\n    const {\n      width,\n      height\n    } = getRectDims(this.data.rect);\n    let elementWidth, elementHeight;\n    if (angle % 180 === 0) {\n      elementWidth = 100 * width / pageWidth;\n      elementHeight = 100 * height / pageHeight;\n    } else {\n      elementWidth = 100 * height / pageWidth;\n      elementHeight = 100 * width / pageHeight;\n    }\n    container.style.width = `${elementWidth}%`;\n    container.style.height = `${elementHeight}%`;\n    container.setAttribute(\"data-main-rotation\", (360 - angle) % 360);\n  }\n  get _commonActions() {\n    const setColor = (jsName, styleName, event) => {\n      const color = event.detail[jsName];\n      const colorType = color[0];\n      const colorArray = color.slice(1);\n      event.target.style[styleName] = ColorConverters[`${colorType}_HTML`](colorArray);\n      this.annotationStorage.setValue(this.data.id, {\n        [styleName]: ColorConverters[`${colorType}_rgb`](colorArray)\n      });\n    };\n    return (0,util.shadow)(this, \"_commonActions\", {\n      display: event => {\n        const {\n          display\n        } = event.detail;\n        const hidden = display % 2 === 1;\n        this.container.style.visibility = hidden ? \"hidden\" : \"visible\";\n        this.annotationStorage.setValue(this.data.id, {\n          noView: hidden,\n          noPrint: display === 1 || display === 2\n        });\n      },\n      print: event => {\n        this.annotationStorage.setValue(this.data.id, {\n          noPrint: !event.detail.print\n        });\n      },\n      hidden: event => {\n        const {\n          hidden\n        } = event.detail;\n        this.container.style.visibility = hidden ? \"hidden\" : \"visible\";\n        this.annotationStorage.setValue(this.data.id, {\n          noPrint: hidden,\n          noView: hidden\n        });\n      },\n      focus: event => {\n        setTimeout(() => event.target.focus({\n          preventScroll: false\n        }), 0);\n      },\n      userName: event => {\n        event.target.title = event.detail.userName;\n      },\n      readonly: event => {\n        event.target.disabled = event.detail.readonly;\n      },\n      required: event => {\n        this._setRequired(event.target, event.detail.required);\n      },\n      bgColor: event => {\n        setColor(\"bgColor\", \"backgroundColor\", event);\n      },\n      fillColor: event => {\n        setColor(\"fillColor\", \"backgroundColor\", event);\n      },\n      fgColor: event => {\n        setColor(\"fgColor\", \"color\", event);\n      },\n      textColor: event => {\n        setColor(\"textColor\", \"color\", event);\n      },\n      borderColor: event => {\n        setColor(\"borderColor\", \"borderColor\", event);\n      },\n      strokeColor: event => {\n        setColor(\"strokeColor\", \"borderColor\", event);\n      },\n      rotation: event => {\n        const angle = event.detail.rotation;\n        this.setRotation(angle);\n        this.annotationStorage.setValue(this.data.id, {\n          rotation: angle\n        });\n      }\n    });\n  }\n  _dispatchEventFromSandbox(actions, jsEvent) {\n    const commonActions = this._commonActions;\n    for (const name of Object.keys(jsEvent.detail)) {\n      const action = actions[name] || commonActions[name];\n      action?.(jsEvent);\n    }\n  }\n  _setDefaultPropertiesFromJS(element) {\n    if (!this.enableScripting) {\n      return;\n    }\n    const storedData = this.annotationStorage.getRawValue(this.data.id);\n    if (!storedData) {\n      return;\n    }\n    const commonActions = this._commonActions;\n    for (const [actionName, detail] of Object.entries(storedData)) {\n      const action = commonActions[actionName];\n      if (action) {\n        const eventProxy = {\n          detail: {\n            [actionName]: detail\n          },\n          target: element\n        };\n        action(eventProxy);\n        delete storedData[actionName];\n      }\n    }\n  }\n  _createQuadrilaterals() {\n    if (!this.container) {\n      return;\n    }\n    const {\n      quadPoints\n    } = this.data;\n    if (!quadPoints) {\n      return;\n    }\n    const [rectBlX, rectBlY, rectTrX, rectTrY] = this.data.rect;\n    if (quadPoints.length === 1) {\n      const [, {\n        x: trX,\n        y: trY\n      }, {\n        x: blX,\n        y: blY\n      }] = quadPoints[0];\n      if (rectTrX === trX && rectTrY === trY && rectBlX === blX && rectBlY === blY) {\n        return;\n      }\n    }\n    const {\n      style\n    } = this.container;\n    let svgBuffer;\n    if (this.#hasBorder) {\n      const {\n        borderColor,\n        borderWidth\n      } = style;\n      style.borderWidth = 0;\n      svgBuffer = [\"url('data:image/svg+xml;utf8,\", `<svg xmlns=\"http://www.w3.org/2000/svg\"`, ` preserveAspectRatio=\"none\" viewBox=\"0 0 1 1\">`, `<g fill=\"transparent\" stroke=\"${borderColor}\" stroke-width=\"${borderWidth}\">`];\n      this.container.classList.add(\"hasBorder\");\n    }\n    const width = rectTrX - rectBlX;\n    const height = rectTrY - rectBlY;\n    const {\n      svgFactory\n    } = this;\n    const svg = svgFactory.createElement(\"svg\");\n    svg.classList.add(\"quadrilateralsContainer\");\n    svg.setAttribute(\"width\", 0);\n    svg.setAttribute(\"height\", 0);\n    const defs = svgFactory.createElement(\"defs\");\n    svg.append(defs);\n    const clipPath = svgFactory.createElement(\"clipPath\");\n    const id = `clippath_${this.data.id}`;\n    clipPath.setAttribute(\"id\", id);\n    clipPath.setAttribute(\"clipPathUnits\", \"objectBoundingBox\");\n    defs.append(clipPath);\n    for (const [, {\n      x: trX,\n      y: trY\n    }, {\n      x: blX,\n      y: blY\n    }] of quadPoints) {\n      const rect = svgFactory.createElement(\"rect\");\n      const x = (blX - rectBlX) / width;\n      const y = (rectTrY - trY) / height;\n      const rectWidth = (trX - blX) / width;\n      const rectHeight = (trY - blY) / height;\n      rect.setAttribute(\"x\", x);\n      rect.setAttribute(\"y\", y);\n      rect.setAttribute(\"width\", rectWidth);\n      rect.setAttribute(\"height\", rectHeight);\n      clipPath.append(rect);\n      svgBuffer?.push(`<rect vector-effect=\"non-scaling-stroke\" x=\"${x}\" y=\"${y}\" width=\"${rectWidth}\" height=\"${rectHeight}\"/>`);\n    }\n    if (this.#hasBorder) {\n      svgBuffer.push(`</g></svg>')`);\n      style.backgroundImage = svgBuffer.join(\"\");\n    }\n    this.container.append(svg);\n    this.container.style.clipPath = `url(#${id})`;\n  }\n  _createPopup() {\n    const {\n      container,\n      data\n    } = this;\n    container.setAttribute(\"aria-haspopup\", \"dialog\");\n    const popup = new PopupAnnotationElement({\n      data: {\n        color: data.color,\n        titleObj: data.titleObj,\n        modificationDate: data.modificationDate,\n        contentsObj: data.contentsObj,\n        richText: data.richText,\n        parentRect: data.rect,\n        borderStyle: 0,\n        id: `popup_${data.id}`,\n        rotation: data.rotation\n      },\n      parent: this.parent,\n      elements: [this]\n    });\n    this.parent.div.append(popup.render());\n  }\n  render() {\n    (0,util.unreachable)(\"Abstract method `AnnotationElement.render` called\");\n  }\n  _getElementsByName(name, skipId = null) {\n    const fields = [];\n    if (this._fieldObjects) {\n      const fieldObj = this._fieldObjects[name];\n      if (fieldObj) {\n        for (const {\n          page,\n          id,\n          exportValues\n        } of fieldObj) {\n          if (page === -1) {\n            continue;\n          }\n          if (id === skipId) {\n            continue;\n          }\n          const exportValue = typeof exportValues === \"string\" ? exportValues : null;\n          const domElement = document.querySelector(`[data-element-id=\"${id}\"]`);\n          if (domElement && !GetElementsByNameSet.has(domElement)) {\n            (0,util.warn)(`_getElementsByName - element not allowed: ${id}`);\n            continue;\n          }\n          fields.push({\n            id,\n            exportValue,\n            domElement\n          });\n        }\n      }\n      return fields;\n    }\n    for (const domElement of document.getElementsByName(name)) {\n      const {\n        exportValue\n      } = domElement;\n      const id = domElement.getAttribute(\"data-element-id\");\n      if (id === skipId) {\n        continue;\n      }\n      if (!GetElementsByNameSet.has(domElement)) {\n        continue;\n      }\n      fields.push({\n        id,\n        exportValue,\n        domElement\n      });\n    }\n    return fields;\n  }\n  show() {\n    if (this.container) {\n      this.container.hidden = false;\n    }\n    this.popup?.maybeShow();\n  }\n  hide() {\n    if (this.container) {\n      this.container.hidden = true;\n    }\n    this.popup?.forceHide();\n  }\n  getElementsToTriggerPopup() {\n    return this.container;\n  }\n  addHighlightArea() {\n    const triggers = this.getElementsToTriggerPopup();\n    if (Array.isArray(triggers)) {\n      for (const element of triggers) {\n        element.classList.add(\"highlightArea\");\n      }\n    } else {\n      triggers.classList.add(\"highlightArea\");\n    }\n  }\n  get _isEditable() {\n    return false;\n  }\n  _editOnDoubleClick() {\n    if (!this._isEditable) {\n      return;\n    }\n    const {\n      annotationEditorType: mode,\n      data: {\n        id: editId\n      }\n    } = this;\n    this.container.addEventListener(\"dblclick\", () => {\n      this.linkService.eventBus?.dispatch(\"switchannotationeditormode\", {\n        source: this,\n        mode,\n        editId\n      });\n    });\n  }\n}\nclass LinkAnnotationElement extends AnnotationElement {\n  constructor(parameters, options = null) {\n    super(parameters, {\n      isRenderable: true,\n      ignoreBorder: !!options?.ignoreBorder,\n      createQuadrilaterals: true\n    });\n    this.isTooltipOnly = parameters.data.isTooltipOnly;\n  }\n  render() {\n    const {\n      data,\n      linkService\n    } = this;\n    const link = document.createElement(\"a\");\n    link.setAttribute(\"data-element-id\", data.id);\n    let isBound = false;\n    if (data.url) {\n      linkService.addLinkAttributes(link, data.url, data.newWindow);\n      isBound = true;\n    } else if (data.action) {\n      this._bindNamedAction(link, data.action);\n      isBound = true;\n    } else if (data.attachment) {\n      this.#bindAttachment(link, data.attachment, data.attachmentDest);\n      isBound = true;\n    } else if (data.setOCGState) {\n      this.#bindSetOCGState(link, data.setOCGState);\n      isBound = true;\n    } else if (data.dest) {\n      this._bindLink(link, data.dest);\n      isBound = true;\n    } else {\n      if (data.actions && (data.actions.Action || data.actions[\"Mouse Up\"] || data.actions[\"Mouse Down\"]) && this.enableScripting && this.hasJSActions) {\n        this._bindJSAction(link, data);\n        isBound = true;\n      }\n      if (data.resetForm) {\n        this._bindResetFormAction(link, data.resetForm);\n        isBound = true;\n      } else if (this.isTooltipOnly && !isBound) {\n        this._bindLink(link, \"\");\n        isBound = true;\n      }\n    }\n    this.container.classList.add(\"linkAnnotation\");\n    if (isBound) {\n      this.container.append(link);\n    }\n    return this.container;\n  }\n  #setInternalLink() {\n    this.container.setAttribute(\"data-internal-link\", \"\");\n  }\n  _bindLink(link, destination) {\n    link.href = this.linkService.getDestinationHash(destination);\n    link.onclick = () => {\n      if (destination) {\n        this.linkService.goToDestination(destination);\n      }\n      return false;\n    };\n    if (destination || destination === \"\") {\n      this.#setInternalLink();\n    }\n  }\n  _bindNamedAction(link, action) {\n    link.href = this.linkService.getAnchorUrl(\"\");\n    link.onclick = () => {\n      this.linkService.executeNamedAction(action);\n      return false;\n    };\n    this.#setInternalLink();\n  }\n  #bindAttachment(link, attachment, dest = null) {\n    link.href = this.linkService.getAnchorUrl(\"\");\n    link.onclick = () => {\n      this.downloadManager?.openOrDownloadData(attachment.content, attachment.filename, dest);\n      return false;\n    };\n    this.#setInternalLink();\n  }\n  #bindSetOCGState(link, action) {\n    link.href = this.linkService.getAnchorUrl(\"\");\n    link.onclick = () => {\n      this.linkService.executeSetOCGState(action);\n      return false;\n    };\n    this.#setInternalLink();\n  }\n  _bindJSAction(link, data) {\n    link.href = this.linkService.getAnchorUrl(\"\");\n    const map = new Map([[\"Action\", \"onclick\"], [\"Mouse Up\", \"onmouseup\"], [\"Mouse Down\", \"onmousedown\"]]);\n    for (const name of Object.keys(data.actions)) {\n      const jsName = map.get(name);\n      if (!jsName) {\n        continue;\n      }\n      link[jsName] = () => {\n        this.linkService.eventBus?.dispatch(\"dispatcheventinsandbox\", {\n          source: this,\n          detail: {\n            id: data.id,\n            name\n          }\n        });\n        return false;\n      };\n    }\n    if (!link.onclick) {\n      link.onclick = () => false;\n    }\n    this.#setInternalLink();\n  }\n  _bindResetFormAction(link, resetForm) {\n    const otherClickAction = link.onclick;\n    if (!otherClickAction) {\n      link.href = this.linkService.getAnchorUrl(\"\");\n    }\n    this.#setInternalLink();\n    if (!this._fieldObjects) {\n      (0,util.warn)(`_bindResetFormAction - \"resetForm\" action not supported, ` + \"ensure that the `fieldObjects` parameter is provided.\");\n      if (!otherClickAction) {\n        link.onclick = () => false;\n      }\n      return;\n    }\n    link.onclick = () => {\n      otherClickAction?.();\n      const {\n        fields: resetFormFields,\n        refs: resetFormRefs,\n        include\n      } = resetForm;\n      const allFields = [];\n      if (resetFormFields.length !== 0 || resetFormRefs.length !== 0) {\n        const fieldIds = new Set(resetFormRefs);\n        for (const fieldName of resetFormFields) {\n          const fields = this._fieldObjects[fieldName] || [];\n          for (const {\n            id\n          } of fields) {\n            fieldIds.add(id);\n          }\n        }\n        for (const fields of Object.values(this._fieldObjects)) {\n          for (const field of fields) {\n            if (fieldIds.has(field.id) === include) {\n              allFields.push(field);\n            }\n          }\n        }\n      } else {\n        for (const fields of Object.values(this._fieldObjects)) {\n          allFields.push(...fields);\n        }\n      }\n      const storage = this.annotationStorage;\n      const allIds = [];\n      for (const field of allFields) {\n        const {\n          id\n        } = field;\n        allIds.push(id);\n        switch (field.type) {\n          case \"text\":\n            {\n              const value = field.defaultValue || \"\";\n              storage.setValue(id, {\n                value\n              });\n              break;\n            }\n          case \"checkbox\":\n          case \"radiobutton\":\n            {\n              const value = field.defaultValue === field.exportValues;\n              storage.setValue(id, {\n                value\n              });\n              break;\n            }\n          case \"combobox\":\n          case \"listbox\":\n            {\n              const value = field.defaultValue || \"\";\n              storage.setValue(id, {\n                value\n              });\n              break;\n            }\n          default:\n            continue;\n        }\n        const domElement = document.querySelector(`[data-element-id=\"${id}\"]`);\n        if (!domElement) {\n          continue;\n        } else if (!GetElementsByNameSet.has(domElement)) {\n          (0,util.warn)(`_bindResetFormAction - element not allowed: ${id}`);\n          continue;\n        }\n        domElement.dispatchEvent(new Event(\"resetform\"));\n      }\n      if (this.enableScripting) {\n        this.linkService.eventBus?.dispatch(\"dispatcheventinsandbox\", {\n          source: this,\n          detail: {\n            id: \"app\",\n            ids: allIds,\n            name: \"ResetForm\"\n          }\n        });\n      }\n      return false;\n    };\n  }\n}\nclass TextAnnotationElement extends AnnotationElement {\n  constructor(parameters) {\n    super(parameters, {\n      isRenderable: true\n    });\n  }\n  render() {\n    this.container.classList.add(\"textAnnotation\");\n    const image = document.createElement(\"img\");\n    image.src = this.imageResourcesPath + \"annotation-\" + this.data.name.toLowerCase() + \".svg\";\n    image.setAttribute(\"data-l10n-id\", \"pdfjs-text-annotation-type\");\n    image.setAttribute(\"data-l10n-args\", JSON.stringify({\n      type: this.data.name\n    }));\n    if (!this.data.popupRef && this.hasPopupData) {\n      this._createPopup();\n    }\n    this.container.append(image);\n    return this.container;\n  }\n}\nclass WidgetAnnotationElement extends AnnotationElement {\n  render() {\n    if (this.data.alternativeText) {\n      this.container.title = this.data.alternativeText;\n    }\n    return this.container;\n  }\n  showElementAndHideCanvas(element) {\n    if (this.data.hasOwnCanvas) {\n      if (element.previousSibling?.nodeName === \"CANVAS\") {\n        element.previousSibling.hidden = true;\n      }\n      element.hidden = false;\n    }\n  }\n  _getKeyModifier(event) {\n    return util.FeatureTest.platform.isMac ? event.metaKey : event.ctrlKey;\n  }\n  _setEventListener(element, elementData, baseName, eventName, valueGetter) {\n    if (baseName.includes(\"mouse\")) {\n      element.addEventListener(baseName, event => {\n        this.linkService.eventBus?.dispatch(\"dispatcheventinsandbox\", {\n          source: this,\n          detail: {\n            id: this.data.id,\n            name: eventName,\n            value: valueGetter(event),\n            shift: event.shiftKey,\n            modifier: this._getKeyModifier(event)\n          }\n        });\n      });\n    } else {\n      element.addEventListener(baseName, event => {\n        if (baseName === \"blur\") {\n          if (!elementData.focused || !event.relatedTarget) {\n            return;\n          }\n          elementData.focused = false;\n        } else if (baseName === \"focus\") {\n          if (elementData.focused) {\n            return;\n          }\n          elementData.focused = true;\n        }\n        if (!valueGetter) {\n          return;\n        }\n        this.linkService.eventBus?.dispatch(\"dispatcheventinsandbox\", {\n          source: this,\n          detail: {\n            id: this.data.id,\n            name: eventName,\n            value: valueGetter(event)\n          }\n        });\n      });\n    }\n  }\n  _setEventListeners(element, elementData, names, getter) {\n    for (const [baseName, eventName] of names) {\n      if (eventName === \"Action\" || this.data.actions?.[eventName]) {\n        if (eventName === \"Focus\" || eventName === \"Blur\") {\n          elementData ||= {\n            focused: false\n          };\n        }\n        this._setEventListener(element, elementData, baseName, eventName, getter);\n        if (eventName === \"Focus\" && !this.data.actions?.Blur) {\n          this._setEventListener(element, elementData, \"blur\", \"Blur\", null);\n        } else if (eventName === \"Blur\" && !this.data.actions?.Focus) {\n          this._setEventListener(element, elementData, \"focus\", \"Focus\", null);\n        }\n      }\n    }\n  }\n  _setBackgroundColor(element) {\n    const color = this.data.backgroundColor || null;\n    element.style.backgroundColor = color === null ? \"transparent\" : util.Util.makeHexColor(color[0], color[1], color[2]);\n  }\n  _setTextStyle(element) {\n    const TEXT_ALIGNMENT = [\"left\", \"center\", \"right\"];\n    const {\n      fontColor\n    } = this.data.defaultAppearanceData;\n    const fontSize = this.data.defaultAppearanceData.fontSize || DEFAULT_FONT_SIZE;\n    const style = element.style;\n    let computedFontSize;\n    const BORDER_SIZE = 2;\n    const roundToOneDecimal = x => Math.round(10 * x) / 10;\n    if (this.data.multiLine) {\n      const height = Math.abs(this.data.rect[3] - this.data.rect[1] - BORDER_SIZE);\n      const numberOfLines = Math.round(height / (util.LINE_FACTOR * fontSize)) || 1;\n      const lineHeight = height / numberOfLines;\n      computedFontSize = Math.min(fontSize, roundToOneDecimal(lineHeight / util.LINE_FACTOR));\n    } else {\n      const height = Math.abs(this.data.rect[3] - this.data.rect[1] - BORDER_SIZE);\n      computedFontSize = Math.min(fontSize, roundToOneDecimal(height / util.LINE_FACTOR));\n    }\n    style.fontSize = `calc(${computedFontSize}px * var(--scale-factor))`;\n    style.color = util.Util.makeHexColor(fontColor[0], fontColor[1], fontColor[2]);\n    if (this.data.textAlignment !== null) {\n      style.textAlign = TEXT_ALIGNMENT[this.data.textAlignment];\n    }\n  }\n  _setRequired(element, isRequired) {\n    if (isRequired) {\n      element.setAttribute(\"required\", true);\n    } else {\n      element.removeAttribute(\"required\");\n    }\n    element.setAttribute(\"aria-required\", isRequired);\n  }\n}\nclass TextWidgetAnnotationElement extends WidgetAnnotationElement {\n  constructor(parameters) {\n    const isRenderable = parameters.renderForms || parameters.data.hasOwnCanvas || !parameters.data.hasAppearance && !!parameters.data.fieldValue;\n    super(parameters, {\n      isRenderable\n    });\n  }\n  setPropertyOnSiblings(base, key, value, keyInStorage) {\n    const storage = this.annotationStorage;\n    for (const element of this._getElementsByName(base.name, base.id)) {\n      if (element.domElement) {\n        element.domElement[key] = value;\n      }\n      storage.setValue(element.id, {\n        [keyInStorage]: value\n      });\n    }\n  }\n  render() {\n    const storage = this.annotationStorage;\n    const id = this.data.id;\n    this.container.classList.add(\"textWidgetAnnotation\");\n    let element = null;\n    if (this.renderForms) {\n      const storedData = storage.getValue(id, {\n        value: this.data.fieldValue\n      });\n      let textContent = storedData.value || \"\";\n      const maxLen = storage.getValue(id, {\n        charLimit: this.data.maxLen\n      }).charLimit;\n      if (maxLen && textContent.length > maxLen) {\n        textContent = textContent.slice(0, maxLen);\n      }\n      let fieldFormattedValues = storedData.formattedValue || this.data.textContent?.join(\"\\n\") || null;\n      if (fieldFormattedValues && this.data.comb) {\n        fieldFormattedValues = fieldFormattedValues.replaceAll(/\\s+/g, \"\");\n      }\n      const elementData = {\n        userValue: textContent,\n        formattedValue: fieldFormattedValues,\n        lastCommittedValue: null,\n        commitKey: 1,\n        focused: false\n      };\n      if (this.data.multiLine) {\n        element = document.createElement(\"textarea\");\n        element.textContent = fieldFormattedValues ?? textContent;\n        if (this.data.doNotScroll) {\n          element.style.overflowY = \"hidden\";\n        }\n      } else {\n        element = document.createElement(\"input\");\n        element.type = \"text\";\n        element.setAttribute(\"value\", fieldFormattedValues ?? textContent);\n        if (this.data.doNotScroll) {\n          element.style.overflowX = \"hidden\";\n        }\n      }\n      if (this.data.hasOwnCanvas) {\n        element.hidden = true;\n      }\n      GetElementsByNameSet.add(element);\n      element.setAttribute(\"data-element-id\", id);\n      element.disabled = this.data.readOnly;\n      element.name = this.data.fieldName;\n      element.tabIndex = DEFAULT_TAB_INDEX;\n      this._setRequired(element, this.data.required);\n      if (maxLen) {\n        element.maxLength = maxLen;\n      }\n      element.addEventListener(\"input\", event => {\n        storage.setValue(id, {\n          value: event.target.value\n        });\n        this.setPropertyOnSiblings(element, \"value\", event.target.value, \"value\");\n        elementData.formattedValue = null;\n      });\n      element.addEventListener(\"resetform\", event => {\n        const defaultValue = this.data.defaultFieldValue ?? \"\";\n        element.value = elementData.userValue = defaultValue;\n        elementData.formattedValue = null;\n      });\n      let blurListener = event => {\n        const {\n          formattedValue\n        } = elementData;\n        if (formattedValue !== null && formattedValue !== undefined) {\n          event.target.value = formattedValue;\n        }\n        event.target.scrollLeft = 0;\n      };\n      if (this.enableScripting && this.hasJSActions) {\n        element.addEventListener(\"focus\", event => {\n          if (elementData.focused) {\n            return;\n          }\n          const {\n            target\n          } = event;\n          if (elementData.userValue) {\n            target.value = elementData.userValue;\n          }\n          elementData.lastCommittedValue = target.value;\n          elementData.commitKey = 1;\n          if (!this.data.actions?.Focus) {\n            elementData.focused = true;\n          }\n        });\n        element.addEventListener(\"updatefromsandbox\", jsEvent => {\n          this.showElementAndHideCanvas(jsEvent.target);\n          const actions = {\n            value(event) {\n              elementData.userValue = event.detail.value ?? \"\";\n              storage.setValue(id, {\n                value: elementData.userValue.toString()\n              });\n              event.target.value = elementData.userValue;\n            },\n            formattedValue(event) {\n              const {\n                formattedValue\n              } = event.detail;\n              elementData.formattedValue = formattedValue;\n              if (formattedValue !== null && formattedValue !== undefined && event.target !== document.activeElement) {\n                event.target.value = formattedValue;\n              }\n              storage.setValue(id, {\n                formattedValue\n              });\n            },\n            selRange(event) {\n              event.target.setSelectionRange(...event.detail.selRange);\n            },\n            charLimit: event => {\n              const {\n                charLimit\n              } = event.detail;\n              const {\n                target\n              } = event;\n              if (charLimit === 0) {\n                target.removeAttribute(\"maxLength\");\n                return;\n              }\n              target.setAttribute(\"maxLength\", charLimit);\n              let value = elementData.userValue;\n              if (!value || value.length <= charLimit) {\n                return;\n              }\n              value = value.slice(0, charLimit);\n              target.value = elementData.userValue = value;\n              storage.setValue(id, {\n                value\n              });\n              this.linkService.eventBus?.dispatch(\"dispatcheventinsandbox\", {\n                source: this,\n                detail: {\n                  id,\n                  name: \"Keystroke\",\n                  value,\n                  willCommit: true,\n                  commitKey: 1,\n                  selStart: target.selectionStart,\n                  selEnd: target.selectionEnd\n                }\n              });\n            }\n          };\n          this._dispatchEventFromSandbox(actions, jsEvent);\n        });\n        element.addEventListener(\"keydown\", event => {\n          elementData.commitKey = 1;\n          let commitKey = -1;\n          if (event.key === \"Escape\") {\n            commitKey = 0;\n          } else if (event.key === \"Enter\" && !this.data.multiLine) {\n            commitKey = 2;\n          } else if (event.key === \"Tab\") {\n            elementData.commitKey = 3;\n          }\n          if (commitKey === -1) {\n            return;\n          }\n          const {\n            value\n          } = event.target;\n          if (elementData.lastCommittedValue === value) {\n            return;\n          }\n          elementData.lastCommittedValue = value;\n          elementData.userValue = value;\n          this.linkService.eventBus?.dispatch(\"dispatcheventinsandbox\", {\n            source: this,\n            detail: {\n              id,\n              name: \"Keystroke\",\n              value,\n              willCommit: true,\n              commitKey,\n              selStart: event.target.selectionStart,\n              selEnd: event.target.selectionEnd\n            }\n          });\n        });\n        const _blurListener = blurListener;\n        blurListener = null;\n        element.addEventListener(\"blur\", event => {\n          if (!elementData.focused || !event.relatedTarget) {\n            return;\n          }\n          if (!this.data.actions?.Blur) {\n            elementData.focused = false;\n          }\n          const {\n            value\n          } = event.target;\n          elementData.userValue = value;\n          if (elementData.lastCommittedValue !== value) {\n            this.linkService.eventBus?.dispatch(\"dispatcheventinsandbox\", {\n              source: this,\n              detail: {\n                id,\n                name: \"Keystroke\",\n                value,\n                willCommit: true,\n                commitKey: elementData.commitKey,\n                selStart: event.target.selectionStart,\n                selEnd: event.target.selectionEnd\n              }\n            });\n          }\n          _blurListener(event);\n        });\n        if (this.data.actions?.Keystroke) {\n          element.addEventListener(\"beforeinput\", event => {\n            elementData.lastCommittedValue = null;\n            const {\n              data,\n              target\n            } = event;\n            const {\n              value,\n              selectionStart,\n              selectionEnd\n            } = target;\n            let selStart = selectionStart,\n              selEnd = selectionEnd;\n            switch (event.inputType) {\n              case \"deleteWordBackward\":\n                {\n                  const match = value.substring(0, selectionStart).match(/\\w*[^\\w]*$/);\n                  if (match) {\n                    selStart -= match[0].length;\n                  }\n                  break;\n                }\n              case \"deleteWordForward\":\n                {\n                  const match = value.substring(selectionStart).match(/^[^\\w]*\\w*/);\n                  if (match) {\n                    selEnd += match[0].length;\n                  }\n                  break;\n                }\n              case \"deleteContentBackward\":\n                if (selectionStart === selectionEnd) {\n                  selStart -= 1;\n                }\n                break;\n              case \"deleteContentForward\":\n                if (selectionStart === selectionEnd) {\n                  selEnd += 1;\n                }\n                break;\n            }\n            event.preventDefault();\n            this.linkService.eventBus?.dispatch(\"dispatcheventinsandbox\", {\n              source: this,\n              detail: {\n                id,\n                name: \"Keystroke\",\n                value,\n                change: data || \"\",\n                willCommit: false,\n                selStart,\n                selEnd\n              }\n            });\n          });\n        }\n        this._setEventListeners(element, elementData, [[\"focus\", \"Focus\"], [\"blur\", \"Blur\"], [\"mousedown\", \"Mouse Down\"], [\"mouseenter\", \"Mouse Enter\"], [\"mouseleave\", \"Mouse Exit\"], [\"mouseup\", \"Mouse Up\"]], event => event.target.value);\n      }\n      if (blurListener) {\n        element.addEventListener(\"blur\", blurListener);\n      }\n      if (this.data.comb) {\n        const fieldWidth = this.data.rect[2] - this.data.rect[0];\n        const combWidth = fieldWidth / maxLen;\n        element.classList.add(\"comb\");\n        element.style.letterSpacing = `calc(${combWidth}px * var(--scale-factor) - 1ch)`;\n      }\n    } else {\n      element = document.createElement(\"div\");\n      element.textContent = this.data.fieldValue;\n      element.style.verticalAlign = \"middle\";\n      element.style.display = \"table-cell\";\n      if (this.data.hasOwnCanvas) {\n        element.hidden = true;\n      }\n    }\n    this._setTextStyle(element);\n    this._setBackgroundColor(element);\n    this._setDefaultPropertiesFromJS(element);\n    this.container.append(element);\n    return this.container;\n  }\n}\nclass SignatureWidgetAnnotationElement extends WidgetAnnotationElement {\n  constructor(parameters) {\n    super(parameters, {\n      isRenderable: !!parameters.data.hasOwnCanvas\n    });\n  }\n}\nclass CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {\n  constructor(parameters) {\n    super(parameters, {\n      isRenderable: parameters.renderForms\n    });\n  }\n  render() {\n    const storage = this.annotationStorage;\n    const data = this.data;\n    const id = data.id;\n    let value = storage.getValue(id, {\n      value: data.exportValue === data.fieldValue\n    }).value;\n    if (typeof value === \"string\") {\n      value = value !== \"Off\";\n      storage.setValue(id, {\n        value\n      });\n    }\n    this.container.classList.add(\"buttonWidgetAnnotation\", \"checkBox\");\n    const element = document.createElement(\"input\");\n    GetElementsByNameSet.add(element);\n    element.setAttribute(\"data-element-id\", id);\n    element.disabled = data.readOnly;\n    this._setRequired(element, this.data.required);\n    element.type = \"checkbox\";\n    element.name = data.fieldName;\n    if (value) {\n      element.setAttribute(\"checked\", true);\n    }\n    element.setAttribute(\"exportValue\", data.exportValue);\n    element.tabIndex = DEFAULT_TAB_INDEX;\n    element.addEventListener(\"change\", event => {\n      const {\n        name,\n        checked\n      } = event.target;\n      for (const checkbox of this._getElementsByName(name, id)) {\n        const curChecked = checked && checkbox.exportValue === data.exportValue;\n        if (checkbox.domElement) {\n          checkbox.domElement.checked = curChecked;\n        }\n        storage.setValue(checkbox.id, {\n          value: curChecked\n        });\n      }\n      storage.setValue(id, {\n        value: checked\n      });\n    });\n    element.addEventListener(\"resetform\", event => {\n      const defaultValue = data.defaultFieldValue || \"Off\";\n      event.target.checked = defaultValue === data.exportValue;\n    });\n    if (this.enableScripting && this.hasJSActions) {\n      element.addEventListener(\"updatefromsandbox\", jsEvent => {\n        const actions = {\n          value(event) {\n            event.target.checked = event.detail.value !== \"Off\";\n            storage.setValue(id, {\n              value: event.target.checked\n            });\n          }\n        };\n        this._dispatchEventFromSandbox(actions, jsEvent);\n      });\n      this._setEventListeners(element, null, [[\"change\", \"Validate\"], [\"change\", \"Action\"], [\"focus\", \"Focus\"], [\"blur\", \"Blur\"], [\"mousedown\", \"Mouse Down\"], [\"mouseenter\", \"Mouse Enter\"], [\"mouseleave\", \"Mouse Exit\"], [\"mouseup\", \"Mouse Up\"]], event => event.target.checked);\n    }\n    this._setBackgroundColor(element);\n    this._setDefaultPropertiesFromJS(element);\n    this.container.append(element);\n    return this.container;\n  }\n}\nclass RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {\n  constructor(parameters) {\n    super(parameters, {\n      isRenderable: parameters.renderForms\n    });\n  }\n  render() {\n    this.container.classList.add(\"buttonWidgetAnnotation\", \"radioButton\");\n    const storage = this.annotationStorage;\n    const data = this.data;\n    const id = data.id;\n    let value = storage.getValue(id, {\n      value: data.fieldValue === data.buttonValue\n    }).value;\n    if (typeof value === \"string\") {\n      value = value !== data.buttonValue;\n      storage.setValue(id, {\n        value\n      });\n    }\n    if (value) {\n      for (const radio of this._getElementsByName(data.fieldName, id)) {\n        storage.setValue(radio.id, {\n          value: false\n        });\n      }\n    }\n    const element = document.createElement(\"input\");\n    GetElementsByNameSet.add(element);\n    element.setAttribute(\"data-element-id\", id);\n    element.disabled = data.readOnly;\n    this._setRequired(element, this.data.required);\n    element.type = \"radio\";\n    element.name = data.fieldName;\n    if (value) {\n      element.setAttribute(\"checked\", true);\n    }\n    element.tabIndex = DEFAULT_TAB_INDEX;\n    element.addEventListener(\"change\", event => {\n      const {\n        name,\n        checked\n      } = event.target;\n      for (const radio of this._getElementsByName(name, id)) {\n        storage.setValue(radio.id, {\n          value: false\n        });\n      }\n      storage.setValue(id, {\n        value: checked\n      });\n    });\n    element.addEventListener(\"resetform\", event => {\n      const defaultValue = data.defaultFieldValue;\n      event.target.checked = defaultValue !== null && defaultValue !== undefined && defaultValue === data.buttonValue;\n    });\n    if (this.enableScripting && this.hasJSActions) {\n      const pdfButtonValue = data.buttonValue;\n      element.addEventListener(\"updatefromsandbox\", jsEvent => {\n        const actions = {\n          value: event => {\n            const checked = pdfButtonValue === event.detail.value;\n            for (const radio of this._getElementsByName(event.target.name)) {\n              const curChecked = checked && radio.id === id;\n              if (radio.domElement) {\n                radio.domElement.checked = curChecked;\n              }\n              storage.setValue(radio.id, {\n                value: curChecked\n              });\n            }\n          }\n        };\n        this._dispatchEventFromSandbox(actions, jsEvent);\n      });\n      this._setEventListeners(element, null, [[\"change\", \"Validate\"], [\"change\", \"Action\"], [\"focus\", \"Focus\"], [\"blur\", \"Blur\"], [\"mousedown\", \"Mouse Down\"], [\"mouseenter\", \"Mouse Enter\"], [\"mouseleave\", \"Mouse Exit\"], [\"mouseup\", \"Mouse Up\"]], event => event.target.checked);\n    }\n    this._setBackgroundColor(element);\n    this._setDefaultPropertiesFromJS(element);\n    this.container.append(element);\n    return this.container;\n  }\n}\nclass PushButtonWidgetAnnotationElement extends LinkAnnotationElement {\n  constructor(parameters) {\n    super(parameters, {\n      ignoreBorder: parameters.data.hasAppearance\n    });\n  }\n  render() {\n    const container = super.render();\n    container.classList.add(\"buttonWidgetAnnotation\", \"pushButton\");\n    if (this.data.alternativeText) {\n      container.title = this.data.alternativeText;\n    }\n    const linkElement = container.lastChild;\n    if (this.enableScripting && this.hasJSActions && linkElement) {\n      this._setDefaultPropertiesFromJS(linkElement);\n      linkElement.addEventListener(\"updatefromsandbox\", jsEvent => {\n        this._dispatchEventFromSandbox({}, jsEvent);\n      });\n    }\n    return container;\n  }\n}\nclass ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {\n  constructor(parameters) {\n    super(parameters, {\n      isRenderable: parameters.renderForms\n    });\n  }\n  render() {\n    this.container.classList.add(\"choiceWidgetAnnotation\");\n    const storage = this.annotationStorage;\n    const id = this.data.id;\n    const storedData = storage.getValue(id, {\n      value: this.data.fieldValue\n    });\n    const selectElement = document.createElement(\"select\");\n    GetElementsByNameSet.add(selectElement);\n    selectElement.setAttribute(\"data-element-id\", id);\n    selectElement.disabled = this.data.readOnly;\n    this._setRequired(selectElement, this.data.required);\n    selectElement.name = this.data.fieldName;\n    selectElement.tabIndex = DEFAULT_TAB_INDEX;\n    let addAnEmptyEntry = this.data.combo && this.data.options.length > 0;\n    if (!this.data.combo) {\n      selectElement.size = this.data.options.length;\n      if (this.data.multiSelect) {\n        selectElement.multiple = true;\n      }\n    }\n    selectElement.addEventListener(\"resetform\", event => {\n      const defaultValue = this.data.defaultFieldValue;\n      for (const option of selectElement.options) {\n        option.selected = option.value === defaultValue;\n      }\n    });\n    for (const option of this.data.options) {\n      const optionElement = document.createElement(\"option\");\n      optionElement.textContent = option.displayValue;\n      optionElement.value = option.exportValue;\n      if (storedData.value.includes(option.exportValue)) {\n        optionElement.setAttribute(\"selected\", true);\n        addAnEmptyEntry = false;\n      }\n      selectElement.append(optionElement);\n    }\n    let removeEmptyEntry = null;\n    if (addAnEmptyEntry) {\n      const noneOptionElement = document.createElement(\"option\");\n      noneOptionElement.value = \" \";\n      noneOptionElement.setAttribute(\"hidden\", true);\n      noneOptionElement.setAttribute(\"selected\", true);\n      selectElement.prepend(noneOptionElement);\n      removeEmptyEntry = () => {\n        noneOptionElement.remove();\n        selectElement.removeEventListener(\"input\", removeEmptyEntry);\n        removeEmptyEntry = null;\n      };\n      selectElement.addEventListener(\"input\", removeEmptyEntry);\n    }\n    const getValue = isExport => {\n      const name = isExport ? \"value\" : \"textContent\";\n      const {\n        options,\n        multiple\n      } = selectElement;\n      if (!multiple) {\n        return options.selectedIndex === -1 ? null : options[options.selectedIndex][name];\n      }\n      return Array.prototype.filter.call(options, option => option.selected).map(option => option[name]);\n    };\n    let selectedValues = getValue(false);\n    const getItems = event => {\n      const options = event.target.options;\n      return Array.prototype.map.call(options, option => ({\n        displayValue: option.textContent,\n        exportValue: option.value\n      }));\n    };\n    if (this.enableScripting && this.hasJSActions) {\n      selectElement.addEventListener(\"updatefromsandbox\", jsEvent => {\n        const actions = {\n          value(event) {\n            removeEmptyEntry?.();\n            const value = event.detail.value;\n            const values = new Set(Array.isArray(value) ? value : [value]);\n            for (const option of selectElement.options) {\n              option.selected = values.has(option.value);\n            }\n            storage.setValue(id, {\n              value: getValue(true)\n            });\n            selectedValues = getValue(false);\n          },\n          multipleSelection(event) {\n            selectElement.multiple = true;\n          },\n          remove(event) {\n            const options = selectElement.options;\n            const index = event.detail.remove;\n            options[index].selected = false;\n            selectElement.remove(index);\n            if (options.length > 0) {\n              const i = Array.prototype.findIndex.call(options, option => option.selected);\n              if (i === -1) {\n                options[0].selected = true;\n              }\n            }\n            storage.setValue(id, {\n              value: getValue(true),\n              items: getItems(event)\n            });\n            selectedValues = getValue(false);\n          },\n          clear(event) {\n            while (selectElement.length !== 0) {\n              selectElement.remove(0);\n            }\n            storage.setValue(id, {\n              value: null,\n              items: []\n            });\n            selectedValues = getValue(false);\n          },\n          insert(event) {\n            const {\n              index,\n              displayValue,\n              exportValue\n            } = event.detail.insert;\n            const selectChild = selectElement.children[index];\n            const optionElement = document.createElement(\"option\");\n            optionElement.textContent = displayValue;\n            optionElement.value = exportValue;\n            if (selectChild) {\n              selectChild.before(optionElement);\n            } else {\n              selectElement.append(optionElement);\n            }\n            storage.setValue(id, {\n              value: getValue(true),\n              items: getItems(event)\n            });\n            selectedValues = getValue(false);\n          },\n          items(event) {\n            const {\n              items\n            } = event.detail;\n            while (selectElement.length !== 0) {\n              selectElement.remove(0);\n            }\n            for (const item of items) {\n              const {\n                displayValue,\n                exportValue\n              } = item;\n              const optionElement = document.createElement(\"option\");\n              optionElement.textContent = displayValue;\n              optionElement.value = exportValue;\n              selectElement.append(optionElement);\n            }\n            if (selectElement.options.length > 0) {\n              selectElement.options[0].selected = true;\n            }\n            storage.setValue(id, {\n              value: getValue(true),\n              items: getItems(event)\n            });\n            selectedValues = getValue(false);\n          },\n          indices(event) {\n            const indices = new Set(event.detail.indices);\n            for (const option of event.target.options) {\n              option.selected = indices.has(option.index);\n            }\n            storage.setValue(id, {\n              value: getValue(true)\n            });\n            selectedValues = getValue(false);\n          },\n          editable(event) {\n            event.target.disabled = !event.detail.editable;\n          }\n        };\n        this._dispatchEventFromSandbox(actions, jsEvent);\n      });\n      selectElement.addEventListener(\"input\", event => {\n        const exportValue = getValue(true);\n        storage.setValue(id, {\n          value: exportValue\n        });\n        event.preventDefault();\n        this.linkService.eventBus?.dispatch(\"dispatcheventinsandbox\", {\n          source: this,\n          detail: {\n            id,\n            name: \"Keystroke\",\n            value: selectedValues,\n            changeEx: exportValue,\n            willCommit: false,\n            commitKey: 1,\n            keyDown: false\n          }\n        });\n      });\n      this._setEventListeners(selectElement, null, [[\"focus\", \"Focus\"], [\"blur\", \"Blur\"], [\"mousedown\", \"Mouse Down\"], [\"mouseenter\", \"Mouse Enter\"], [\"mouseleave\", \"Mouse Exit\"], [\"mouseup\", \"Mouse Up\"], [\"input\", \"Action\"], [\"input\", \"Validate\"]], event => event.target.value);\n    } else {\n      selectElement.addEventListener(\"input\", function (event) {\n        storage.setValue(id, {\n          value: getValue(true)\n        });\n      });\n    }\n    if (this.data.combo) {\n      this._setTextStyle(selectElement);\n    } else {}\n    this._setBackgroundColor(selectElement);\n    this._setDefaultPropertiesFromJS(selectElement);\n    this.container.append(selectElement);\n    return this.container;\n  }\n}\nclass PopupAnnotationElement extends AnnotationElement {\n  constructor(parameters) {\n    const {\n      data,\n      elements\n    } = parameters;\n    super(parameters, {\n      isRenderable: AnnotationElement._hasPopupData(data)\n    });\n    this.elements = elements;\n  }\n  render() {\n    this.container.classList.add(\"popupAnnotation\");\n    const popup = new PopupElement({\n      container: this.container,\n      color: this.data.color,\n      titleObj: this.data.titleObj,\n      modificationDate: this.data.modificationDate,\n      contentsObj: this.data.contentsObj,\n      richText: this.data.richText,\n      rect: this.data.rect,\n      parentRect: this.data.parentRect || null,\n      parent: this.parent,\n      elements: this.elements,\n      open: this.data.open\n    });\n    const elementIds = [];\n    for (const element of this.elements) {\n      element.popup = popup;\n      elementIds.push(element.data.id);\n      element.addHighlightArea();\n    }\n    this.container.setAttribute(\"aria-controls\", elementIds.map(id => `${util.AnnotationPrefix}${id}`).join(\",\"));\n    return this.container;\n  }\n}\nclass PopupElement {\n  #boundKeyDown = this.#keyDown.bind(this);\n  #boundHide = this.#hide.bind(this);\n  #boundShow = this.#show.bind(this);\n  #boundToggle = this.#toggle.bind(this);\n  #color = null;\n  #container = null;\n  #contentsObj = null;\n  #dateObj = null;\n  #elements = null;\n  #parent = null;\n  #parentRect = null;\n  #pinned = false;\n  #popup = null;\n  #rect = null;\n  #richText = null;\n  #titleObj = null;\n  #wasVisible = false;\n  constructor({\n    container,\n    color,\n    elements,\n    titleObj,\n    modificationDate,\n    contentsObj,\n    richText,\n    parent,\n    rect,\n    parentRect,\n    open\n  }) {\n    this.#container = container;\n    this.#titleObj = titleObj;\n    this.#contentsObj = contentsObj;\n    this.#richText = richText;\n    this.#parent = parent;\n    this.#color = color;\n    this.#rect = rect;\n    this.#parentRect = parentRect;\n    this.#elements = elements;\n    this.#dateObj = display_utils.PDFDateString.toDateObject(modificationDate);\n    this.trigger = elements.flatMap(e => e.getElementsToTriggerPopup());\n    for (const element of this.trigger) {\n      element.addEventListener(\"click\", this.#boundToggle);\n      element.addEventListener(\"mouseenter\", this.#boundShow);\n      element.addEventListener(\"mouseleave\", this.#boundHide);\n      element.classList.add(\"popupTriggerArea\");\n    }\n    for (const element of elements) {\n      element.container?.addEventListener(\"keydown\", this.#boundKeyDown);\n    }\n    this.#container.hidden = true;\n    if (open) {\n      this.#toggle();\n    }\n  }\n  render() {\n    if (this.#popup) {\n      return;\n    }\n    const {\n      page: {\n        view\n      },\n      viewport: {\n        rawDims: {\n          pageWidth,\n          pageHeight,\n          pageX,\n          pageY\n        }\n      }\n    } = this.#parent;\n    const popup = this.#popup = document.createElement(\"div\");\n    popup.className = \"popup\";\n    if (this.#color) {\n      const baseColor = popup.style.outlineColor = util.Util.makeHexColor(...this.#color);\n      if (CSS.supports(\"background-color\", \"color-mix(in srgb, red 30%, white)\")) {\n        popup.style.backgroundColor = `color-mix(in srgb, ${baseColor} 30%, white)`;\n      } else {\n        const BACKGROUND_ENLIGHT = 0.7;\n        popup.style.backgroundColor = util.Util.makeHexColor(...this.#color.map(c => Math.floor(BACKGROUND_ENLIGHT * (255 - c) + c)));\n      }\n    }\n    const header = document.createElement(\"span\");\n    header.className = \"header\";\n    const title = document.createElement(\"h1\");\n    header.append(title);\n    ({\n      dir: title.dir,\n      str: title.textContent\n    } = this.#titleObj);\n    popup.append(header);\n    if (this.#dateObj) {\n      const modificationDate = document.createElement(\"span\");\n      modificationDate.classList.add(\"popupDate\");\n      modificationDate.setAttribute(\"data-l10n-id\", \"pdfjs-annotation-date-string\");\n      modificationDate.setAttribute(\"data-l10n-args\", JSON.stringify({\n        date: this.#dateObj.toLocaleDateString(),\n        time: this.#dateObj.toLocaleTimeString()\n      }));\n      header.append(modificationDate);\n    }\n    const contentsObj = this.#contentsObj;\n    const richText = this.#richText;\n    if (richText?.str && (!contentsObj?.str || contentsObj.str === richText.str)) {\n      xfa_layer.XfaLayer.render({\n        xfaHtml: richText.html,\n        intent: \"richText\",\n        div: popup\n      });\n      popup.lastChild.classList.add(\"richText\", \"popupContent\");\n    } else {\n      const contents = this._formatContents(contentsObj);\n      popup.append(contents);\n    }\n    let useParentRect = !!this.#parentRect;\n    let rect = useParentRect ? this.#parentRect : this.#rect;\n    for (const element of this.#elements) {\n      if (!rect || util.Util.intersect(element.data.rect, rect) !== null) {\n        rect = element.data.rect;\n        useParentRect = true;\n        break;\n      }\n    }\n    const normalizedRect = util.Util.normalizeRect([rect[0], view[3] - rect[1] + view[1], rect[2], view[3] - rect[3] + view[1]]);\n    const HORIZONTAL_SPACE_AFTER_ANNOTATION = 5;\n    const parentWidth = useParentRect ? rect[2] - rect[0] + HORIZONTAL_SPACE_AFTER_ANNOTATION : 0;\n    const popupLeft = normalizedRect[0] + parentWidth;\n    const popupTop = normalizedRect[1];\n    const {\n      style\n    } = this.#container;\n    style.left = `${100 * (popupLeft - pageX) / pageWidth}%`;\n    style.top = `${100 * (popupTop - pageY) / pageHeight}%`;\n    this.#container.append(popup);\n  }\n  _formatContents({\n    str,\n    dir\n  }) {\n    const p = document.createElement(\"p\");\n    p.classList.add(\"popupContent\");\n    p.dir = dir;\n    const lines = str.split(/(?:\\r\\n?|\\n)/);\n    for (let i = 0, ii = lines.length; i < ii; ++i) {\n      const line = lines[i];\n      p.append(document.createTextNode(line));\n      if (i < ii - 1) {\n        p.append(document.createElement(\"br\"));\n      }\n    }\n    return p;\n  }\n  #keyDown(event) {\n    if (event.altKey || event.shiftKey || event.ctrlKey || event.metaKey) {\n      return;\n    }\n    if (event.key === \"Enter\" || event.key === \"Escape\" && this.#pinned) {\n      this.#toggle();\n    }\n  }\n  #toggle() {\n    this.#pinned = !this.#pinned;\n    if (this.#pinned) {\n      this.#show();\n      this.#container.addEventListener(\"click\", this.#boundToggle);\n      this.#container.addEventListener(\"keydown\", this.#boundKeyDown);\n    } else {\n      this.#hide();\n      this.#container.removeEventListener(\"click\", this.#boundToggle);\n      this.#container.removeEventListener(\"keydown\", this.#boundKeyDown);\n    }\n  }\n  #show() {\n    if (!this.#popup) {\n      this.render();\n    }\n    if (!this.isVisible) {\n      this.#container.hidden = false;\n      this.#container.style.zIndex = parseInt(this.#container.style.zIndex) + 1000;\n    } else if (this.#pinned) {\n      this.#container.classList.add(\"focused\");\n    }\n  }\n  #hide() {\n    this.#container.classList.remove(\"focused\");\n    if (this.#pinned || !this.isVisible) {\n      return;\n    }\n    this.#container.hidden = true;\n    this.#container.style.zIndex = parseInt(this.#container.style.zIndex) - 1000;\n  }\n  forceHide() {\n    this.#wasVisible = this.isVisible;\n    if (!this.#wasVisible) {\n      return;\n    }\n    this.#container.hidden = true;\n  }\n  maybeShow() {\n    if (!this.#wasVisible) {\n      return;\n    }\n    this.#wasVisible = false;\n    this.#container.hidden = false;\n  }\n  get isVisible() {\n    return this.#container.hidden === false;\n  }\n}\nclass FreeTextAnnotationElement extends AnnotationElement {\n  constructor(parameters) {\n    super(parameters, {\n      isRenderable: true,\n      ignoreBorder: true\n    });\n    this.textContent = parameters.data.textContent;\n    this.textPosition = parameters.data.textPosition;\n    this.annotationEditorType = util.AnnotationEditorType.FREETEXT;\n  }\n  render() {\n    this.container.classList.add(\"freeTextAnnotation\");\n    if (this.textContent) {\n      const content = document.createElement(\"div\");\n      content.classList.add(\"annotationTextContent\");\n      content.setAttribute(\"role\", \"comment\");\n      for (const line of this.textContent) {\n        const lineSpan = document.createElement(\"span\");\n        lineSpan.textContent = line;\n        content.append(lineSpan);\n      }\n      this.container.append(content);\n    }\n    if (!this.data.popupRef && this.hasPopupData) {\n      this._createPopup();\n    }\n    this._editOnDoubleClick();\n    return this.container;\n  }\n  get _isEditable() {\n    return this.data.hasOwnCanvas;\n  }\n}\nclass LineAnnotationElement extends AnnotationElement {\n  #line = null;\n  constructor(parameters) {\n    super(parameters, {\n      isRenderable: true,\n      ignoreBorder: true\n    });\n  }\n  render() {\n    this.container.classList.add(\"lineAnnotation\");\n    const data = this.data;\n    const {\n      width,\n      height\n    } = getRectDims(data.rect);\n    const svg = this.svgFactory.create(width, height, true);\n    const line = this.#line = this.svgFactory.createElement(\"svg:line\");\n    line.setAttribute(\"x1\", data.rect[2] - data.lineCoordinates[0]);\n    line.setAttribute(\"y1\", data.rect[3] - data.lineCoordinates[1]);\n    line.setAttribute(\"x2\", data.rect[2] - data.lineCoordinates[2]);\n    line.setAttribute(\"y2\", data.rect[3] - data.lineCoordinates[3]);\n    line.setAttribute(\"stroke-width\", data.borderStyle.width || 1);\n    line.setAttribute(\"stroke\", \"transparent\");\n    line.setAttribute(\"fill\", \"transparent\");\n    svg.append(line);\n    this.container.append(svg);\n    if (!data.popupRef && this.hasPopupData) {\n      this._createPopup();\n    }\n    return this.container;\n  }\n  getElementsToTriggerPopup() {\n    return this.#line;\n  }\n  addHighlightArea() {\n    this.container.classList.add(\"highlightArea\");\n  }\n}\nclass SquareAnnotationElement extends AnnotationElement {\n  #square = null;\n  constructor(parameters) {\n    super(parameters, {\n      isRenderable: true,\n      ignoreBorder: true\n    });\n  }\n  render() {\n    this.container.classList.add(\"squareAnnotation\");\n    const data = this.data;\n    const {\n      width,\n      height\n    } = getRectDims(data.rect);\n    const svg = this.svgFactory.create(width, height, true);\n    const borderWidth = data.borderStyle.width;\n    const square = this.#square = this.svgFactory.createElement(\"svg:rect\");\n    square.setAttribute(\"x\", borderWidth / 2);\n    square.setAttribute(\"y\", borderWidth / 2);\n    square.setAttribute(\"width\", width - borderWidth);\n    square.setAttribute(\"height\", height - borderWidth);\n    square.setAttribute(\"stroke-width\", borderWidth || 1);\n    square.setAttribute(\"stroke\", \"transparent\");\n    square.setAttribute(\"fill\", \"transparent\");\n    svg.append(square);\n    this.container.append(svg);\n    if (!data.popupRef && this.hasPopupData) {\n      this._createPopup();\n    }\n    return this.container;\n  }\n  getElementsToTriggerPopup() {\n    return this.#square;\n  }\n  addHighlightArea() {\n    this.container.classList.add(\"highlightArea\");\n  }\n}\nclass CircleAnnotationElement extends AnnotationElement {\n  #circle = null;\n  constructor(parameters) {\n    super(parameters, {\n      isRenderable: true,\n      ignoreBorder: true\n    });\n  }\n  render() {\n    this.container.classList.add(\"circleAnnotation\");\n    const data = this.data;\n    const {\n      width,\n      height\n    } = getRectDims(data.rect);\n    const svg = this.svgFactory.create(width, height, true);\n    const borderWidth = data.borderStyle.width;\n    const circle = this.#circle = this.svgFactory.createElement(\"svg:ellipse\");\n    circle.setAttribute(\"cx\", width / 2);\n    circle.setAttribute(\"cy\", height / 2);\n    circle.setAttribute(\"rx\", width / 2 - borderWidth / 2);\n    circle.setAttribute(\"ry\", height / 2 - borderWidth / 2);\n    circle.setAttribute(\"stroke-width\", borderWidth || 1);\n    circle.setAttribute(\"stroke\", \"transparent\");\n    circle.setAttribute(\"fill\", \"transparent\");\n    svg.append(circle);\n    this.container.append(svg);\n    if (!data.popupRef && this.hasPopupData) {\n      this._createPopup();\n    }\n    return this.container;\n  }\n  getElementsToTriggerPopup() {\n    return this.#circle;\n  }\n  addHighlightArea() {\n    this.container.classList.add(\"highlightArea\");\n  }\n}\nclass PolylineAnnotationElement extends AnnotationElement {\n  #polyline = null;\n  constructor(parameters) {\n    super(parameters, {\n      isRenderable: true,\n      ignoreBorder: true\n    });\n    this.containerClassName = \"polylineAnnotation\";\n    this.svgElementName = \"svg:polyline\";\n  }\n  render() {\n    this.container.classList.add(this.containerClassName);\n    const data = this.data;\n    const {\n      width,\n      height\n    } = getRectDims(data.rect);\n    const svg = this.svgFactory.create(width, height, true);\n    let points = [];\n    for (const coordinate of data.vertices) {\n      const x = coordinate.x - data.rect[0];\n      const y = data.rect[3] - coordinate.y;\n      points.push(x + \",\" + y);\n    }\n    points = points.join(\" \");\n    const polyline = this.#polyline = this.svgFactory.createElement(this.svgElementName);\n    polyline.setAttribute(\"points\", points);\n    polyline.setAttribute(\"stroke-width\", data.borderStyle.width || 1);\n    polyline.setAttribute(\"stroke\", \"transparent\");\n    polyline.setAttribute(\"fill\", \"transparent\");\n    svg.append(polyline);\n    this.container.append(svg);\n    if (!data.popupRef && this.hasPopupData) {\n      this._createPopup();\n    }\n    return this.container;\n  }\n  getElementsToTriggerPopup() {\n    return this.#polyline;\n  }\n  addHighlightArea() {\n    this.container.classList.add(\"highlightArea\");\n  }\n}\nclass PolygonAnnotationElement extends PolylineAnnotationElement {\n  constructor(parameters) {\n    super(parameters);\n    this.containerClassName = \"polygonAnnotation\";\n    this.svgElementName = \"svg:polygon\";\n  }\n}\nclass CaretAnnotationElement extends AnnotationElement {\n  constructor(parameters) {\n    super(parameters, {\n      isRenderable: true,\n      ignoreBorder: true\n    });\n  }\n  render() {\n    this.container.classList.add(\"caretAnnotation\");\n    if (!this.data.popupRef && this.hasPopupData) {\n      this._createPopup();\n    }\n    return this.container;\n  }\n}\nclass InkAnnotationElement extends AnnotationElement {\n  #polylines = [];\n  constructor(parameters) {\n    super(parameters, {\n      isRenderable: true,\n      ignoreBorder: true\n    });\n    this.containerClassName = \"inkAnnotation\";\n    this.svgElementName = \"svg:polyline\";\n    this.annotationEditorType = util.AnnotationEditorType.INK;\n  }\n  render() {\n    this.container.classList.add(this.containerClassName);\n    const data = this.data;\n    const {\n      width,\n      height\n    } = getRectDims(data.rect);\n    const svg = this.svgFactory.create(width, height, true);\n    for (const inkList of data.inkLists) {\n      let points = [];\n      for (const coordinate of inkList) {\n        const x = coordinate.x - data.rect[0];\n        const y = data.rect[3] - coordinate.y;\n        points.push(`${x},${y}`);\n      }\n      points = points.join(\" \");\n      const polyline = this.svgFactory.createElement(this.svgElementName);\n      this.#polylines.push(polyline);\n      polyline.setAttribute(\"points\", points);\n      polyline.setAttribute(\"stroke-width\", data.borderStyle.width || 1);\n      polyline.setAttribute(\"stroke\", \"transparent\");\n      polyline.setAttribute(\"fill\", \"transparent\");\n      if (!data.popupRef && this.hasPopupData) {\n        this._createPopup();\n      }\n      svg.append(polyline);\n    }\n    this.container.append(svg);\n    return this.container;\n  }\n  getElementsToTriggerPopup() {\n    return this.#polylines;\n  }\n  addHighlightArea() {\n    this.container.classList.add(\"highlightArea\");\n  }\n}\nclass HighlightAnnotationElement extends AnnotationElement {\n  constructor(parameters) {\n    super(parameters, {\n      isRenderable: true,\n      ignoreBorder: true,\n      createQuadrilaterals: true\n    });\n  }\n  render() {\n    if (!this.data.popupRef && this.hasPopupData) {\n      this._createPopup();\n    }\n    this.container.classList.add(\"highlightAnnotation\");\n    return this.container;\n  }\n}\nclass UnderlineAnnotationElement extends AnnotationElement {\n  constructor(parameters) {\n    super(parameters, {\n      isRenderable: true,\n      ignoreBorder: true,\n      createQuadrilaterals: true\n    });\n  }\n  render() {\n    if (!this.data.popupRef && this.hasPopupData) {\n      this._createPopup();\n    }\n    this.container.classList.add(\"underlineAnnotation\");\n    return this.container;\n  }\n}\nclass SquigglyAnnotationElement extends AnnotationElement {\n  constructor(parameters) {\n    super(parameters, {\n      isRenderable: true,\n      ignoreBorder: true,\n      createQuadrilaterals: true\n    });\n  }\n  render() {\n    if (!this.data.popupRef && this.hasPopupData) {\n      this._createPopup();\n    }\n    this.container.classList.add(\"squigglyAnnotation\");\n    return this.container;\n  }\n}\nclass StrikeOutAnnotationElement extends AnnotationElement {\n  constructor(parameters) {\n    super(parameters, {\n      isRenderable: true,\n      ignoreBorder: true,\n      createQuadrilaterals: true\n    });\n  }\n  render() {\n    if (!this.data.popupRef && this.hasPopupData) {\n      this._createPopup();\n    }\n    this.container.classList.add(\"strikeoutAnnotation\");\n    return this.container;\n  }\n}\nclass StampAnnotationElement extends AnnotationElement {\n  constructor(parameters) {\n    super(parameters, {\n      isRenderable: true,\n      ignoreBorder: true\n    });\n  }\n  render() {\n    this.container.classList.add(\"stampAnnotation\");\n    if (!this.data.popupRef && this.hasPopupData) {\n      this._createPopup();\n    }\n    return this.container;\n  }\n}\nclass FileAttachmentAnnotationElement extends AnnotationElement {\n  #trigger = null;\n  constructor(parameters) {\n    super(parameters, {\n      isRenderable: true\n    });\n    const {\n      filename,\n      content\n    } = this.data.file;\n    this.filename = (0,display_utils.getFilenameFromUrl)(filename, true);\n    this.content = content;\n    this.linkService.eventBus?.dispatch(\"fileattachmentannotation\", {\n      source: this,\n      filename,\n      content\n    });\n  }\n  render() {\n    this.container.classList.add(\"fileAttachmentAnnotation\");\n    const {\n      container,\n      data\n    } = this;\n    let trigger;\n    if (data.hasAppearance || data.fillAlpha === 0) {\n      trigger = document.createElement(\"div\");\n    } else {\n      trigger = document.createElement(\"img\");\n      trigger.src = `${this.imageResourcesPath}annotation-${/paperclip/i.test(data.name) ? \"paperclip\" : \"pushpin\"}.svg`;\n      if (data.fillAlpha && data.fillAlpha < 1) {\n        trigger.style = `filter: opacity(${Math.round(data.fillAlpha * 100)}%);`;\n      }\n    }\n    trigger.addEventListener(\"dblclick\", this.#download.bind(this));\n    this.#trigger = trigger;\n    const {\n      isMac\n    } = util.FeatureTest.platform;\n    container.addEventListener(\"keydown\", evt => {\n      if (evt.key === \"Enter\" && (isMac ? evt.metaKey : evt.ctrlKey)) {\n        this.#download();\n      }\n    });\n    if (!data.popupRef && this.hasPopupData) {\n      this._createPopup();\n    } else {\n      trigger.classList.add(\"popupTriggerArea\");\n    }\n    container.append(trigger);\n    return container;\n  }\n  getElementsToTriggerPopup() {\n    return this.#trigger;\n  }\n  addHighlightArea() {\n    this.container.classList.add(\"highlightArea\");\n  }\n  #download() {\n    this.downloadManager?.openOrDownloadData(this.content, this.filename);\n  }\n}\nclass AnnotationLayer {\n  #accessibilityManager = null;\n  #annotationCanvasMap = null;\n  #editableAnnotations = new Map();\n  constructor({\n    div,\n    accessibilityManager,\n    annotationCanvasMap,\n    page,\n    viewport\n  }) {\n    this.div = div;\n    this.#accessibilityManager = accessibilityManager;\n    this.#annotationCanvasMap = annotationCanvasMap;\n    this.page = page;\n    this.viewport = viewport;\n    this.zIndex = 0;\n  }\n  #appendElement(element, id) {\n    const contentElement = element.firstChild || element;\n    contentElement.id = `${util.AnnotationPrefix}${id}`;\n    this.div.append(element);\n    this.#accessibilityManager?.moveElementInDOM(this.div, element, contentElement, false);\n  }\n  async render(params) {\n    const {\n      annotations\n    } = params;\n    const layer = this.div;\n    (0,display_utils.setLayerDimensions)(layer, this.viewport);\n    const popupToElements = new Map();\n    const elementParams = {\n      data: null,\n      layer,\n      linkService: params.linkService,\n      downloadManager: params.downloadManager,\n      imageResourcesPath: params.imageResourcesPath || \"\",\n      renderForms: params.renderForms !== false,\n      svgFactory: new display_utils.DOMSVGFactory(),\n      annotationStorage: params.annotationStorage || new annotation_storage.AnnotationStorage(),\n      enableScripting: params.enableScripting === true,\n      hasJSActions: params.hasJSActions,\n      fieldObjects: params.fieldObjects,\n      parent: this,\n      elements: null\n    };\n    for (const data of annotations) {\n      if (data.noHTML) {\n        continue;\n      }\n      const isPopupAnnotation = data.annotationType === util.AnnotationType.POPUP;\n      if (!isPopupAnnotation) {\n        const {\n          width,\n          height\n        } = getRectDims(data.rect);\n        if (width <= 0 || height <= 0) {\n          continue;\n        }\n      } else {\n        const elements = popupToElements.get(data.id);\n        if (!elements) {\n          continue;\n        }\n        elementParams.elements = elements;\n      }\n      elementParams.data = data;\n      const element = AnnotationElementFactory.create(elementParams);\n      if (!element.isRenderable) {\n        continue;\n      }\n      if (!isPopupAnnotation && data.popupRef) {\n        const elements = popupToElements.get(data.popupRef);\n        if (!elements) {\n          popupToElements.set(data.popupRef, [element]);\n        } else {\n          elements.push(element);\n        }\n      }\n      if (element.annotationEditorType > 0) {\n        this.#editableAnnotations.set(element.data.id, element);\n      }\n      const rendered = element.render();\n      if (data.hidden) {\n        rendered.style.visibility = \"hidden\";\n      }\n      this.#appendElement(rendered, data.id);\n    }\n    this.#setAnnotationCanvasMap();\n  }\n  update({\n    viewport\n  }) {\n    const layer = this.div;\n    this.viewport = viewport;\n    (0,display_utils.setLayerDimensions)(layer, {\n      rotation: viewport.rotation\n    });\n    this.#setAnnotationCanvasMap();\n    layer.hidden = false;\n  }\n  #setAnnotationCanvasMap() {\n    if (!this.#annotationCanvasMap) {\n      return;\n    }\n    const layer = this.div;\n    for (const [id, canvas] of this.#annotationCanvasMap) {\n      const element = layer.querySelector(`[data-annotation-id=\"${id}\"]`);\n      if (!element) {\n        continue;\n      }\n      const {\n        firstChild\n      } = element;\n      if (!firstChild) {\n        element.append(canvas);\n      } else if (firstChild.nodeName === \"CANVAS\") {\n        firstChild.replaceWith(canvas);\n      } else {\n        firstChild.before(canvas);\n      }\n    }\n    this.#annotationCanvasMap.clear();\n  }\n  getEditableAnnotations() {\n    return Array.from(this.#editableAnnotations.values());\n  }\n  getEditableAnnotation(id) {\n    return this.#editableAnnotations.get(id);\n  }\n}\n\n\n/***/ })\n\n/******/ });\n/************************************************************************/\n/******/ // The module cache\n/******/ var __webpack_module_cache__ = {};\n/******/ \n/******/ // The require function\n/******/ function __webpack_require__(moduleId) {\n/******/ \t// Check if module is in cache\n/******/ \tvar cachedModule = __webpack_module_cache__[moduleId];\n/******/ \tif (cachedModule !== undefined) {\n/******/ \t\treturn cachedModule.exports;\n/******/ \t}\n/******/ \t// Create a new module (and put it into the cache)\n/******/ \tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t// no module.id needed\n/******/ \t\t// no module.loaded needed\n/******/ \t\texports: {}\n/******/ \t};\n/******/ \n/******/ \t// Execute the module function\n/******/ \t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n/******/ \n/******/ \t// Return the exports of the module\n/******/ \treturn module.exports;\n/******/ }\n/******/ \n/************************************************************************/\n/******/ /* webpack/runtime/async module */\n/******/ (() => {\n/******/ \tvar webpackQueues = typeof Symbol === \"function\" ? Symbol(\"webpack queues\") : \"__webpack_queues__\";\n/******/ \tvar webpackExports = typeof Symbol === \"function\" ? Symbol(\"webpack exports\") : \"__webpack_exports__\";\n/******/ \tvar webpackError = typeof Symbol === \"function\" ? Symbol(\"webpack error\") : \"__webpack_error__\";\n/******/ \tvar resolveQueue = (queue) => {\n/******/ \t\tif(queue && queue.d < 1) {\n/******/ \t\t\tqueue.d = 1;\n/******/ \t\t\tqueue.forEach((fn) => (fn.r--));\n/******/ \t\t\tqueue.forEach((fn) => (fn.r-- ? fn.r++ : fn()));\n/******/ \t\t}\n/******/ \t}\n/******/ \tvar wrapDeps = (deps) => (deps.map((dep) => {\n/******/ \t\tif(dep !== null && typeof dep === \"object\") {\n/******/ \t\t\tif(dep[webpackQueues]) return dep;\n/******/ \t\t\tif(dep.then) {\n/******/ \t\t\t\tvar queue = [];\n/******/ \t\t\t\tqueue.d = 0;\n/******/ \t\t\t\tdep.then((r) => {\n/******/ \t\t\t\t\tobj[webpackExports] = r;\n/******/ \t\t\t\t\tresolveQueue(queue);\n/******/ \t\t\t\t}, (e) => {\n/******/ \t\t\t\t\tobj[webpackError] = e;\n/******/ \t\t\t\t\tresolveQueue(queue);\n/******/ \t\t\t\t});\n/******/ \t\t\t\tvar obj = {};\n/******/ \t\t\t\tobj[webpackQueues] = (fn) => (fn(queue));\n/******/ \t\t\t\treturn obj;\n/******/ \t\t\t}\n/******/ \t\t}\n/******/ \t\tvar ret = {};\n/******/ \t\tret[webpackQueues] = x => {};\n/******/ \t\tret[webpackExports] = dep;\n/******/ \t\treturn ret;\n/******/ \t}));\n/******/ \t__webpack_require__.a = (module, body, hasAwait) => {\n/******/ \t\tvar queue;\n/******/ \t\thasAwait && ((queue = []).d = -1);\n/******/ \t\tvar depQueues = new Set();\n/******/ \t\tvar exports = module.exports;\n/******/ \t\tvar currentDeps;\n/******/ \t\tvar outerResolve;\n/******/ \t\tvar reject;\n/******/ \t\tvar promise = new Promise((resolve, rej) => {\n/******/ \t\t\treject = rej;\n/******/ \t\t\touterResolve = resolve;\n/******/ \t\t});\n/******/ \t\tpromise[webpackExports] = exports;\n/******/ \t\tpromise[webpackQueues] = (fn) => (queue && fn(queue), depQueues.forEach(fn), promise[\"catch\"](x => {}));\n/******/ \t\tmodule.exports = promise;\n/******/ \t\tbody((deps) => {\n/******/ \t\t\tcurrentDeps = wrapDeps(deps);\n/******/ \t\t\tvar fn;\n/******/ \t\t\tvar getResult = () => (currentDeps.map((d) => {\n/******/ \t\t\t\tif(d[webpackError]) throw d[webpackError];\n/******/ \t\t\t\treturn d[webpackExports];\n/******/ \t\t\t}))\n/******/ \t\t\tvar promise = new Promise((resolve) => {\n/******/ \t\t\t\tfn = () => (resolve(getResult));\n/******/ \t\t\t\tfn.r = 0;\n/******/ \t\t\t\tvar fnQueue = (q) => (q !== queue && !depQueues.has(q) && (depQueues.add(q), q && !q.d && (fn.r++, q.push(fn))));\n/******/ \t\t\t\tcurrentDeps.map((dep) => (dep[webpackQueues](fnQueue)));\n/******/ \t\t\t});\n/******/ \t\t\treturn fn.r ? promise : getResult();\n/******/ \t\t}, (err) => ((err ? reject(promise[webpackError] = err) : outerResolve(exports)), resolveQueue(queue)));\n/******/ \t\tqueue && queue.d < 0 && (queue.d = 0);\n/******/ \t};\n/******/ })();\n/******/ \n/******/ /* webpack/runtime/define property getters */\n/******/ (() => {\n/******/ \t// define getter functions for harmony exports\n/******/ \t__webpack_require__.d = (exports, definition) => {\n/******/ \t\tfor(var key in definition) {\n/******/ \t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t}\n/******/ \t\t}\n/******/ \t};\n/******/ })();\n/******/ \n/******/ /* webpack/runtime/hasOwnProperty shorthand */\n/******/ (() => {\n/******/ \t__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))\n/******/ })();\n/******/ \n/************************************************************************/\n/******/ \n/******/ // startup\n/******/ // Load entry module and return exports\n/******/ // This entry module used 'module' so it can't be inlined\n/******/ var __webpack_exports__ = __webpack_require__(228);\n/******/ __webpack_exports__ = globalThis.pdfjsLib = await (globalThis.pdfjsLibPromise = __webpack_exports__);\n/******/ const __webpack_exports__AbortException = __webpack_exports__.AbortException;\n/******/ const __webpack_exports__AnnotationEditorLayer = __webpack_exports__.AnnotationEditorLayer;\n/******/ const __webpack_exports__AnnotationEditorParamsType = __webpack_exports__.AnnotationEditorParamsType;\n/******/ const __webpack_exports__AnnotationEditorType = __webpack_exports__.AnnotationEditorType;\n/******/ const __webpack_exports__AnnotationEditorUIManager = __webpack_exports__.AnnotationEditorUIManager;\n/******/ const __webpack_exports__AnnotationLayer = __webpack_exports__.AnnotationLayer;\n/******/ const __webpack_exports__AnnotationMode = __webpack_exports__.AnnotationMode;\n/******/ const __webpack_exports__CMapCompressionType = __webpack_exports__.CMapCompressionType;\n/******/ const __webpack_exports__ColorPicker = __webpack_exports__.ColorPicker;\n/******/ const __webpack_exports__DOMSVGFactory = __webpack_exports__.DOMSVGFactory;\n/******/ const __webpack_exports__DrawLayer = __webpack_exports__.DrawLayer;\n/******/ const __webpack_exports__FeatureTest = __webpack_exports__.FeatureTest;\n/******/ const __webpack_exports__GlobalWorkerOptions = __webpack_exports__.GlobalWorkerOptions;\n/******/ const __webpack_exports__ImageKind = __webpack_exports__.ImageKind;\n/******/ const __webpack_exports__InvalidPDFException = __webpack_exports__.InvalidPDFException;\n/******/ const __webpack_exports__MissingPDFException = __webpack_exports__.MissingPDFException;\n/******/ const __webpack_exports__OPS = __webpack_exports__.OPS;\n/******/ const __webpack_exports__Outliner = __webpack_exports__.Outliner;\n/******/ const __webpack_exports__PDFDataRangeTransport = __webpack_exports__.PDFDataRangeTransport;\n/******/ const __webpack_exports__PDFDateString = __webpack_exports__.PDFDateString;\n/******/ const __webpack_exports__PDFWorker = __webpack_exports__.PDFWorker;\n/******/ const __webpack_exports__PasswordResponses = __webpack_exports__.PasswordResponses;\n/******/ const __webpack_exports__PermissionFlag = __webpack_exports__.PermissionFlag;\n/******/ const __webpack_exports__PixelsPerInch = __webpack_exports__.PixelsPerInch;\n/******/ const __webpack_exports__PromiseCapability = __webpack_exports__.PromiseCapability;\n/******/ const __webpack_exports__RenderingCancelledException = __webpack_exports__.RenderingCancelledException;\n/******/ const __webpack_exports__UnexpectedResponseException = __webpack_exports__.UnexpectedResponseException;\n/******/ const __webpack_exports__Util = __webpack_exports__.Util;\n/******/ const __webpack_exports__VerbosityLevel = __webpack_exports__.VerbosityLevel;\n/******/ const __webpack_exports__XfaLayer = __webpack_exports__.XfaLayer;\n/******/ const __webpack_exports__build = __webpack_exports__.build;\n/******/ const __webpack_exports__createValidAbsoluteUrl = __webpack_exports__.createValidAbsoluteUrl;\n/******/ const __webpack_exports__fetchData = __webpack_exports__.fetchData;\n/******/ const __webpack_exports__getDocument = __webpack_exports__.getDocument;\n/******/ const __webpack_exports__getFilenameFromUrl = __webpack_exports__.getFilenameFromUrl;\n/******/ const __webpack_exports__getPdfFilenameFromUrl = __webpack_exports__.getPdfFilenameFromUrl;\n/******/ const __webpack_exports__getXfaPageViewport = __webpack_exports__.getXfaPageViewport;\n/******/ const __webpack_exports__isDataScheme = __webpack_exports__.isDataScheme;\n/******/ const __webpack_exports__isPdfFile = __webpack_exports__.isPdfFile;\n/******/ const __webpack_exports__noContextMenu = __webpack_exports__.noContextMenu;\n/******/ const __webpack_exports__normalizeUnicode = __webpack_exports__.normalizeUnicode;\n/******/ const __webpack_exports__renderTextLayer = __webpack_exports__.renderTextLayer;\n/******/ const __webpack_exports__setLayerDimensions = __webpack_exports__.setLayerDimensions;\n/******/ const __webpack_exports__shadow = __webpack_exports__.shadow;\n/******/ const __webpack_exports__updateTextLayer = __webpack_exports__.updateTextLayer;\n/******/ const __webpack_exports__version = __webpack_exports__.version;\n/******/ export { __webpack_exports__AbortException as AbortException, __webpack_exports__AnnotationEditorLayer as AnnotationEditorLayer, __webpack_exports__AnnotationEditorParamsType as AnnotationEditorParamsType, __webpack_exports__AnnotationEditorType as AnnotationEditorType, __webpack_exports__AnnotationEditorUIManager as AnnotationEditorUIManager, __webpack_exports__AnnotationLayer as AnnotationLayer, __webpack_exports__AnnotationMode as AnnotationMode, __webpack_exports__CMapCompressionType as CMapCompressionType, __webpack_exports__ColorPicker as ColorPicker, __webpack_exports__DOMSVGFactory as DOMSVGFactory, __webpack_exports__DrawLayer as DrawLayer, __webpack_exports__FeatureTest as FeatureTest, __webpack_exports__GlobalWorkerOptions as GlobalWorkerOptions, __webpack_exports__ImageKind as ImageKind, __webpack_exports__InvalidPDFException as InvalidPDFException, __webpack_exports__MissingPDFException as MissingPDFException, __webpack_exports__OPS as OPS, __webpack_exports__Outliner as Outliner, __webpack_exports__PDFDataRangeTransport as PDFDataRangeTransport, __webpack_exports__PDFDateString as PDFDateString, __webpack_exports__PDFWorker as PDFWorker, __webpack_exports__PasswordResponses as PasswordResponses, __webpack_exports__PermissionFlag as PermissionFlag, __webpack_exports__PixelsPerInch as PixelsPerInch, __webpack_exports__PromiseCapability as PromiseCapability, __webpack_exports__RenderingCancelledException as RenderingCancelledException, __webpack_exports__UnexpectedResponseException as UnexpectedResponseException, __webpack_exports__Util as Util, __webpack_exports__VerbosityLevel as VerbosityLevel, __webpack_exports__XfaLayer as XfaLayer, __webpack_exports__build as build, __webpack_exports__createValidAbsoluteUrl as createValidAbsoluteUrl, __webpack_exports__fetchData as fetchData, __webpack_exports__getDocument as getDocument, __webpack_exports__getFilenameFromUrl as getFilenameFromUrl, __webpack_exports__getPdfFilenameFromUrl as getPdfFilenameFromUrl, __webpack_exports__getXfaPageViewport as getXfaPageViewport, __webpack_exports__isDataScheme as isDataScheme, __webpack_exports__isPdfFile as isPdfFile, __webpack_exports__noContextMenu as noContextMenu, __webpack_exports__normalizeUnicode as normalizeUnicode, __webpack_exports__renderTextLayer as renderTextLayer, __webpack_exports__setLayerDimensions as setLayerDimensions, __webpack_exports__shadow as shadow, __webpack_exports__updateTextLayer as updateTextLayer, __webpack_exports__version as version };\n/******/ \n\n//# sourceMappingURL=pdf.mjs.map"
  },
  {
    "path": "src/vendor/pdfjs/pdf.sandbox.mjs",
    "content": "/**\n * @licstart The following is the entire license notice for the\n * JavaScript code in this page\n *\n * Copyright 2023 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @licend The above is the entire license notice for the\n * JavaScript code in this page\n */\n\n\n;// ./external/quickjs/quickjs-eval.js\nvar Module=(()=>{var _scriptDir=typeof document!=='undefined'&&document.currentScript?document.currentScript.src:undefined;return function(moduleArg={}){var d=moduleArg,k,n;d.ready=new Promise((a,b)=>{k=a;n=b;});var p=Object.assign({},d),q=\"\";\"undefined\"!=typeof document&&document.currentScript&&(q=document.currentScript.src);_scriptDir&&(q=_scriptDir);q.startsWith(\"blob:\")?q=\"\":q=q.substr(0,q.replace(/[?#].*/,\"\").lastIndexOf(\"/\")+1);var aa=d.print||console.error.bind(console),u=d.printErr||console.error.bind(console);Object.assign(d,p);p=null;var v;d.wasmBinary&&(v=d.wasmBinary);\"object\"!=typeof WebAssembly&&w(\"no native wasm support detected\");var x,y=!1,z,A,B,C;function D(){var a=x.buffer;d.HEAP8=z=new Int8Array(a);d.HEAP16=new Int16Array(a);d.HEAPU8=A=new Uint8Array(a);d.HEAPU16=new Uint16Array(a);d.HEAP32=B=new Int32Array(a);d.HEAPU32=C=new Uint32Array(a);d.HEAPF32=new Float32Array(a);d.HEAPF64=new Float64Array(a);}var E=[],F=[],G=[];function ba(){var a=d.preRun.shift();E.unshift(a);}var H=0,I=null,J=null;function w(a){d.onAbort?.(a);a=\"Aborted(\"+a+\")\";u(a);y=!0;a=new WebAssembly.RuntimeError(a+\". Build with -sASSERTIONS for more info.\");n(a);throw a;}var K=a=>a.startsWith(\"data:application/octet-stream;base64,\"),L;L=\"data:application/octet-stream;base64,AGFzbQEAAAABzgZtYAJ/fwBgA39/fwF/YAR/fn9/AX5gAn9/AX9gBX9+f39/AX5gAX8Bf2ADf39/AGAEf39/fwF/YAJ/fgF+YAF/AGABfAF8YAV/f39/fwF/YAJ/fgBgAn9+AX9gAn9/AX5gA39/fgF/YAN/fn8BfmAGf35/f39/AX5gA39+fwBgA39+fwF/YAZ/f39/f38Bf2AEf39/fwBgBn9+fn9/fwF+YAR/f35/AX9gA39+fgF+YAN/f38BfmADf35+AX9gBH9/f38BfmAFf35+fn4AYAJ8fAF8YAF/AX5gBH9/f34Bf2AFf35+f38BfmAFf39/f38AYAd/fn9+fn5/AX9gBX9/f35+AX9gB39/f39/f38Bf2AAAGAFf35/fn8Bf2AEf35+fwBgBH9+fn8BfmAFf35+fn8Bf2AFf39/f38BfmAEf39+fgF/YAF+AX9gBH9+f34BfmAEf35/fwBgBH9+fn8Bf2AJf39/f39/f39/AX9gCH9/f39/f39/AX9gA39+fgBgBH9+f38Bf2AGf35/fn5/AX9gBX9+fn9/AGABfgF+YAd/fn9/f39/AX5gAX8BfGADf39+AGAEf35/fgF/YAV/f35/fwF/YAR/fn5+AX9gBn9/f39/fwF+YAN+f38Bf2AHf39/f39/fwBgAnx/AXxgA39/fgF+YAJ+fwF/YAN8fH8BfGAEf39+fwBgBH9+fn4BfmAAAX9gBn98f39/fwF/YAABfGAFf35/fn8BfmAGf39+fn5+AX9gAn5/AGACf3wAYAV/f39/fgF+YAR/f35/AX5gBH9+f34AYAd/fn5+f39/AX5gBH5+fn4Bf2AKf39/f39/f39/fwF/YAd/f39/f39+AX5gBX9+f39/AGAHfH9/f39/fwBgBX98f39/AX5gAXwBf2AFf39+f38AYAZ/fn5+fn8Bf2AGf35/f39/AX9gBH98f38Bf2AGf39/f39/AGAEf39/fgF+YAV/fn9/fwF/YAV/fn5+fgF/YAJ/fwF8YAV/fn5/fwF/YAV/f35+fgF+YAV/f35+fwF/YAJ8fwF/YAJ8fAF/YAh/fn5+fn9+fgF+YAN/fnwBfmAAAX5gB39/f35+fn8Bf2ACfn4BfGADfn5+AX9gA39/fAACSQwBYQFhABUBYQFiACUBYQFjAAcBYQFkAAYBYQFlAEgBYQFmAAABYQFn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IAILLQEBfwJAIAAoAgAiAUUNACAAKAIQIgBFDQAgASgCACAAQQAgASgCBBEBABoLCzEAIAFBAE4EQCAAQbYBEA0gACABEDggACgCQCIAKAKkAiABQRRsaiAAKAKEAjYCBAsLJwEBfyMAQRBrIgIkACACIAE2AgwgACACQQxqQQQQchogAkEQaiQACxcAIAAgASACQoCAgIAwIAMgBEECENIBCxgBAX4gASkDACEDIAEgAjcDACAAIAMQDAszAQF/IAIEQCAAIQMDQCADIAEtAAA6AAAgA0EBaiEDIAFBAWohASACQQFrIgINAAsLIAALwQUCAn4GfyMAQeAAayIJJAAgA0EAIANBAEobIQsDQCAKIAtHBEAgACACIApBBHRqIgMoAgAQsAUhBiADLQAEIQdCgICAgDAhBAJAAkACQAJAAkACQAJAAkACQAJAIAMtAAUOCgECAgUHAwQIBQAGCyAAIAMoAggQsAUhCAJ+AkACQAJAIAMoAgxBAWoOAwIAAQkLIAAgACkDwAEiBCAIIARBABARDAILIAAgACgCKCkDECIEIAggBEEAEBEMAQsgACABIAggAUEAEBELIQQgACAIEBAgBkHLAUYEQEEBIQcMCAsgBkHUAUcNB0EAIQcMBwsCQCAGQcsBRgRAQQEhBwwBCyAGQdQBRw0AQQAhBwsgACABIAZBAiADIAcQgAMaDAcLIAAgASAGQoCAgIAwIAMoAggEfiAJIAMoAgA2AhAgCUEgaiIIQcAAQeEqIAlBEGoQSBogACADKAIIIAhBAEEKQQggAy0ABUECRhsgAy4BBhCCAQVCgICAgDALIgQgAygCDAR+IAkgAygCADYCACAJQSBqIghBwABB2iogCRBIGiAAIAMoAgwgCEEBQQtBCSADLQAFQQJGGyADLgEGEIIBBUKAgICAMAsiBSAHQYA6chBqGiAAIAQQDCAAIAUQDAwGCyADKQMIIgRCgICAgAh8Qv////8PWARAIARC/////w+DIQQMBQtCgICAgMB+IAS5vSIEQoCAgIDAgYD8/wB9IARC////////////AINCgICAgICAgPj/AFYbIQQMBAtCgICAgMB+IAMpAwgiBEKAgICAwIGA/P8AfSAEQv///////////wCDQoCAgICAgID4/wBWGyEEDAMLIAAgASAGQQIgAyAHEIADGgwDCxABAAsgAzUCCCEECyAAIAEgBiAEIAcQFRoLIAAgBhAQIApBAWohCgwBCwsgCUHgAGokAAuMAgICfgF/AkACQAJAAkACQAJAAkACQAJAQQcgAUIgiKciBCAEQQdrQW5JG0EKag4SAgAGBAAAAAAAAQMFAAAAAAEDAAsgAEGbHkEAEBJCgICAgOAADwsgBEF1SQ0GIAGnIgAgACgCAEEBajYCAAwGCyAAQSEQhgEhAgwECyAAQQQQhgEhAgwDCyAAIABBBRCGASICQTAgAacpAgRC/////weDQQAQFRoMAgsgAEEGEIYBIQIMAQsgAEEHEIYBIQILQoCAgIDgACEDIAJCgICAgHCDQoCAgIDgAFIEfiAEQXVPBEAgAaciBCAEKAIAQQFqNgIACyAAIAIgARC9ASACBUKAgICA4AALDwsgAQsyAQF/AkAgAUIgiKdBdUkNACABpyICIAIoAgAiAkEBazYCACACQQFKDQAgACABEJcFCwsLACAAQeweQQAQEgujBAELfyAAKAIAIQUjAEEQayIIIAI2AgxBfyEJAkADQAJAIAggAiIDQQRqIgI2AgwgAygCACIHQX9GDQAgACgCBCEKA0AgASIEIApODQMgBCAEIAVqIgwtAAAiBkECdEHgrgFqIg0tAABqIgEgCkoNAyAGQcYBRgRAIAwoAAEhCQwBCwsgBiAHRwRAIAdBGHYgBkYgBiAHQRB2Qf8BcUZyIAYgB0H/AXFGckUgBiAHQQh2Qf8BcUdxIAZFIAdBgAJJcnINAyAAIAY2AhALIARBAWohBAJAAkACQAJAAkACQAJAAkAgDS0AA0EFaw4YAAkACQkBCQkBCQkBAQECAgICBAUGBwkDCQsgBCAFai0AACEEIAggA0EIaiICNgIMIAMoAgQiA0F/RgRAIAAgBDYCFAwJCyADIARGDQgMCQsgBCAFai8AACEEIAggA0EIaiICNgIMIAMoAgQiA0F/RgRAIAAgBDYCFAwICyADIARGDQcMCAsgACAEIAVqKAAANgIYDAYLIAAgBCAFaiIDKAAANgIYIAAgAy8ABDYCHAwFCyAAIAQgBWooAAA2AiAMBAsgACAEIAVqIgMoAAA2AiAgACADLQAENgIcDAMLIAAgBCAFaiIDKAAANgIgIAAgAy8ABDYCHAwCCyAAIAQgBWoiAygAADYCICAAIAMoAAQ2AhggACADLQAINgIcDAELCyAAIAk2AgwgACABNgIIQQEhCwsgCwskAQF/IAAoAhAiAkEQaiABIAIoAgARAwAiAUUEQCAAEHALIAELCwAgACABQQAQjQQLJwEBfyMAQRBrIgIkACACIAE7AQ4gACACQQ5qQQIQchogAkEQaiQAC9QBAgR/An5BfyECAkACQAJAAkACQAJAAkAgAUIgiKciA0EKag4RAwUFAgUFBQUFBAABAQEFBQYFCyABp0EARw8LIAGnDwsgAacpAgQhByAAIAEQDCAHQv////8Hg0IAUg8LIAGnKAIMIQQgACABEAwgBEH/////B2pBfkkPCyABpywABSEFIAAgARAMIAVBAE4PCyADQQdrQW1NBEAgAUKAgICAwIGA/P8AfEL///////////8Ag0IBfUKAgICAgICA+P8AVA8LIAAgARAMQQEhAgsgAgs/AQJ/IwBBEGsiAiQAAn8gASAAKAIQRwRAIAIgATYCACAAQcyQASACEBNBfwwBCyAAEA8LIQMgAkEQaiQAIAMLCwAgACABQQEQ6QULGQAgAEEAEFAaIABCgICAgPD/////ADcCBAvDCgIFfxF+IwBB4ABrIgUkACAEQv///////z+DIQwgAiAEhUKAgICAgICAgIB/gyEKIAJC////////P4MiDUIgiCEOIARCMIinQf//AXEhBwJAAkAgAkIwiKdB//8BcSIJQf//AWtBgoB+TwRAIAdB//8Ba0GBgH5LDQELIAFQIAJC////////////AIMiC0KAgICAgIDA//8AVCALQoCAgICAgMD//wBRG0UEQCACQoCAgICAgCCEIQoMAgsgA1AgBEL///////////8AgyICQoCAgICAgMD//wBUIAJCgICAgICAwP//AFEbRQRAIARCgICAgICAIIQhCiADIQEMAgsgASALQoCAgICAgMD//wCFhFAEQCACIAOEUARAQoCAgICAgOD//wAhCkIAIQEMAwsgCkKAgICAgIDA//8AhCEKQgAhAQwCCyADIAJCgICAgICAwP//AIWEUARAIAEgC4QhGUIAIQEgGVAEQEKAgICAgIDg//8AIQoMAwsgCkKAgICAgIDA//8AhCEKDAILIAEgC4RQBEBCACEBDAILIAIgA4RQBEBCACEBDAILIAtC////////P1gEQCAFQdAAaiABIA0gASANIA1QIgYbeSAG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////B4OENwIEIABBADYCBCABrUKAgICAkH+ECwsPACAAKAJAQYACaiABEBsLEwAgACABIAIgAyABQYCAARDQAQsNACAAIAEgAkEGEMgCCx8BAX8gACgCJCIBIAEoAgBBAWo2AgAgACABQQIQ5wULZwECfwJ/IAAoAggiAiAAKAIMTgRAQX8gACACQQFqIAEQxAINARoLIAAgACgCCCIDQQFqNgIIIAAoAgRBEGohAgJAIAAoAhAEQCACIANBAXRqIAE7AQAMAQsgAiADaiABOgAAC0EACwt6AQN/AkACQCAAIgFBA3FFDQAgAS0AAEUEQEEADwsDQCABQQFqIgFBA3FFDQEgAS0AAA0ACwwBCwNAIAEiAkEEaiEBIAIoAgAiA0F/cyADQYGChAhrcUGAgYKEeHFFDQALA0AgAiIBQQFqIQIgAS0AAA0ACwsgASAAawsNACAAIAEgAkEAEJkDCywBAX8jAEEQayIDJAAgAyACNgIMIABB3ABqQYABIAEgAhDJAhogA0EQaiQAC+gDAQl/IwBBIGsiBSQAIAEgAiABKAIMIAIoAgxJIgYbIgcoAgQgAiABIAYbIggoAgRzIQoCQAJAIAcoAgwiAkUEQAJAIAgoAggiAUH/////B0cEQCAHKAIIIgJB/////wdHDQELIAAQKkEAIQIMAwsgAUH+////B0cgAkH+////B0dxRQRAAkAgAUH+////B0YEQCACQYCAgIB4Rg0BDAQLIAFBgICAgHhHIAJB/v///wdHcg0DCyAAECpBASECDAMLIAAgChCAAUEAIQIMAgsgCCgCDCILIQkgAiEGIARBB3FBBkYEQCACIANBIWpBBXYiASABIAJKGyEGIAsgASABIAtKGyEJCwJ/AkAgACAIRg0AIAAgB0YNACAADAELIAAoAgAhASAFQgA3AhggBUKAgICAgICAgIB/NwIQIAUgATYCDCAAIQwgBUEMagshASAHKAIQIQAgCCgCECENAn8gASAGIAlqEFAEQCABECpBIAwBCyABKAIQIA0gC0ECdGogCUECdGsgCSAAIAJBAnRqIAZBAnRrIAYQ8AEgASAKNgIEIAEgBygCCCAIKAIIajYCCCABIAMgBBCbAgshAiABIAVBDGoiAEcNASAMIAAQvwQMAQsgACAKEH9BACECCyAFQSBqJAAgAgsKACAAIAFBARBHCygB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ajAAAEL/////D4MPCyAEKAIoIANNDQggBCgCJCADajEAAA8LIAQoAiggA00NByAEKAIkIANBAXRqMgEAQv////8Pgw8LIAQoAiggA00NBiAEKAIkIANBAXRqMwEADwsgBCgCKCADTQ0FIAQoAiQgA0ECdGo1AgAPCyAEKAIoIANNDQQgBCgCJCADQQJ0aigCACIAQQBOBEAgAK0PC0KAgICAwH4gALi9IgFCgICAgMCBgPz/AH0gAUKAgICAgICA+P8AVhsPCyAEKAIoIANNDQMgACAEKAIkIANBA3RqKQMAEL8CDwsgBCgCKCADTQ0CIAAgBCgCJCADQQN0aikDABCIBA8LIAQoAiggA00NAUKAgICAwH4gBCgCJCADQQJ0aioCALu9IgFCgICAgMCBgPz/AH0gAUL///////////8Ag0KAgICAgICA+P8AVhsPCyAEKAIoIANNDQBCgICAgMB+IAQoAiQgA0EDdGopAwAiAUKAgICAwIGA/P8AfSABQv///////////wCDQoCAgICAgID4/wBWGw8LIAAgAhAwIQMgACACEAwgA0UEQEKAgICA4AAPCyAAIAEgAyABQQAQESEBIAAgAxAQCyABC4IDAgR/An4CQCAAKQNwIgVQRSAFIAApA3ggACgCBCIBIAAoAiwiAmusfCIGV3FFBEAjAEEQayICJABBfyEBAkACfyAAIAAoAkgiA0EBayADcjYCSCAAKAIUIAAoAhxHBEAgAEEAQQAgACgCJBEBABoLIABBADYCHCAAQgA3AxAgACgCACIDQQRxBEAgACADQSByNgIAQX8MAQsgACAAKAIsIAAoAjBqIgQ2AgggACAENgIEIANBG3RBH3ULDQAgACACQQ9qQQEgACgCIBEBAEEBRw0AIAItAA8hAQsgAkEQaiQAIAEiA0EATg0BIAAoAgQhASAAKAIsIQILIABCfzcDcCAAIAE2AmggACAGIAIgAWusfDcDeEF/DwsgBkIBfCEGIAAoAgQhASAAKAIIIQICQCAAKQNwIgVQDQAgBSAGfSIFIAIgAWusWQ0AIAEgBadqIQILIAAgAjYCaCAAIAYgACgCLCIAIAFrrHw3A3ggACABTwRAIAFBAWsgAzoAAAsgAwtPAQF/An9BACAAKAIMIAFGDQAaIAAoAgAiAigCACAAKAIQIAFBAnQgAigCBBEBACECIAEEQEF/IAJFDQEaCyAAIAE2AgwgACACNgIQQQALC9EBAQZ/IABBAWohBQJAAkAgAC0AACIDwCIHQQBOBEAgBSEBDAELQX8hBCAHQUBrQf8BcSIDQT1LDQEgA0ECdEGU9gFqKAIAIgYgAU4NASAGQQFrIQggACAGakEBaiEBIAcgBkHz9QFqLQAAcSEDQQAhAANAIAAgBkcEQCAFLAAAIgRBv39KBEBBfw8FIARBP3EgA0EGdHIhAyAAQQFqIQAgBUEBaiEFDAILAAsLQX8hBCADIAhBAnRBgPYBaigCAEkNAQsgAiABNgIAIAMhBAsgBAsLACAAIAFBABDpBQsJACAAQQEQrQELugEBAn8CQAJAIAJC/////wdYBEAgACABIAKnQYCAgIB4chBuIgRBAEwNASAAIAEgAhBOIgJCgICAgHCDQoCAgIDgAFINAkF/IQQMAgsgACACEIsDIgVFBEBBfyEEDAELAkAgACABIAUQbiIEQQBMBEBCgICAgDAhAgwBCyAAIAEgBSABQQAQESICQoCAgIBwg0KAgICA4ABSDQBBfyEECyAAIAUQEAwBC0KAgICAMCECCyADIAI3AwAgBAsbAQF/IAAgARA1BH9BAAUgAEH7OUEAEBJBfwsLYwEBfyACQiCIp0F1TwRAIAKnIgUgBSgCAEEBajYCAAsCQCAAIAEgAhDTBSIFDQACQCABKAIAIgBBAEgEQCAAIARqIgBBACAAQQBKGyEDDAELIAAgA0wNAQsgASADNgIACyAFCxgAIAAtAABBIHFFBEAgASACIAAQlwQaCwsPACAAKAJAQYACaiABEA4LrgIAAkACQAJAAkAgAkEDTARAAkACQAJAAkACQAJAAkACQAJAIAFB2ABrDgkAAQIDBAUGBwgKCyAAIAJBO2tB/wFxEA4PCyAAIAJBN2tB/wFxEA4PCyAAIAJBM2tB/wFxEA4PCyAAIAJBL2tB/wFxEA4PCyAAIAJBK2tB/wFxEA4PCyAAIAJBJ2tB/wFxEA4PCyAAIAJBI2tB/wFxEA4PCyAAIAJBH2tB/wFxEA4PCyAAIAJBG2tB/wFxEA4PCyACQf8BSw0BAkACQAJAIAFB2ABrDgMAAQIECyAAQcIBEA4MBQsgAEHDARAODAQLIABBxAEQDgwDCyABQSJGDQELIAAgAUH/AXEQDiAAIAJB//8DcRAmDwsgACACQRJrQf8BcRAODwsgACACQf8BcRAOCzgBAX8CQAJAIAFCgICAgHBUDQAgAaciAy8BBiACRw0AIAMoAiAiAw0BCyAAIAIQigNBACEDCyADC0EBAX8gAQRAA0AgAiADRkUEQCAAIAEgA0EDdGooAgQQECADQQFqIQMMAQsLIAAoAhAiAEEQaiABIAAoAgQRAAALCywBAX8gACgCECICQRBqIAEgAigCABEDACICBEAgAkEAIAEQLA8LIAAQcCACC20BAX8jAEGAAmsiBSQAIARBgMAEcSACIANMckUEQCAFIAFB/wFxIAIgA2siA0GAAiADQYACSSIBGxAsGiABRQRAA0AgACAFQYACEFcgA0GAAmsiA0H/AUsNAAsLIAAgBSADEFcLIAVBgAJqJAALvgECAn4BfwJAAkAgAUKAgICAcINCgICAgDBRBEAgACgCKCACQQN0aikDACIDQiCIp0F0Sw0BDAILIAAgAUE8IAFBABARIgNCgICAgHCDQoCAgIDgAFEEQCADDwsgA0L/////b1YNASAAIAMQDCAAIAEQ/AIiBUUEQEKAgICA4AAPCyAFKAIoIAJBA3RqKQMAIgNCIIinQXVJDQELIAOnIgUgBSgCAEEBajYCAAsgACADIAIQRyEEIAAgAxAMIAQLDAAgAEHZ6gBBABASCw0AIAAgASABED0Q6gELdQEBfiAAIAEgBH4gAiADfnwgA0IgiCICIAFCIIgiBH58IANC/////w+DIgMgAUL/////D4MiAX4iBUIgiCADIAR+fCIDQiCIfCABIAJ+IANC/////w+DfCIBQiCIfDcDCCAAIAVC/////w+DIAFCIIaENwMAC1ABAX4CQCADQcAAcQRAIAEgA0FAaq2GIQJCACEBDAELIANFDQAgAiADrSIEhiABQcAAIANrrYiEIQIgASAEhiEBCyAAIAE3AwAgACACNwMIC2QAAkACQCABQQBIDQAgACgCrAIgAUwNACAAKAKkAiABQRRsaiIAIAAoAgAgAmoiADYCACAAQQBIDQEgAA8LQdwXQajsAEHzpwFBr8MAEAAAC0HphQFBqOwAQfanAUGvwwAQAAALcAECfyAEIAMoAgBKBH8jAEEQayIFJAAgACABKAIAIAQgAygCAEEDbEECbSIAIAAgBEgbIgAgAmwgBUEMahCnASIEBH8gAyAFKAIMIAJu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EGsiBCQAAkAgAkIgiKciA0ECTQRAIAEgAqe3OQMAQQAhAwwBCyADQQdrQW1NBEAgASACQoCAgIDAgYD8/wB8NwMAQQAhAwwBCwJ/IAAgAhCWASICQoCAgIBwg0KAgICA4ABRBEBEAAAAAAAA+H8hBUF/DAELAnwCQAJAQQcgAkIgiKciAyADQQdrQW5JGyIDQXZHBEAgA0EHRg0CIAMNASACp7cMAwsgAqdBBGogBEEIahCxBCAAIAIQDCAEKwMIIQVBAAwDCxABAAsgAkKAgICAwIGA/P8AfL8LIQVBAAshAyABIAU5AwALIARBEGokACADC90BAQN/AkAgAUKAgICAcFoEQCABpyEDA0ACQCADLQAFQQRxRQ0AIAAoAhAoAkQgAy8BBkEYbGooAhQiBEUNACAEKAIQIgRFDQAgAyADKAIAQQFqNgIAIAAgA61CgICAgHCEIgEgAiAEERMAIQUgACABEAwgBQ8LIAMgAygCAEEBajYCACAAQQAgAyACEEMhBCAAIAOtQoCAgIBwhBAMIAQNAgJAIAMvAQZBFWtB//8DcUEKSw0AIAAgAhCTAyIERQ0AIARBH3UPCyADKAIQKAIsIgMNAAsLQQAhBAsgBAvNCQIEfwV+IwBB8ABrIgYkACAEQv///////////wCDIQkCQAJAIAFQIgUgAkL///////////8AgyIKQoCAgICAgMD//wB9QoCAgICAgMCAgH9UIApQG0UEQCADQgBSIAlCgICAgICAwP//AH0iC0KAgICAgIDAgIB/ViALQoCAgICAgMCAgH9RGw0BCyAFIApCgICAgICAwP//AFQgCkKAgICAgIDA//8AURtFBEAgAkKAgICAgIAghCEEIAEhAwwCCyADUCAJQoCAgICAgMD//wBUIAlCgICAgICAwP//AFEbRQRAIARCgICAgICAIIQhBAwCCyABIApCgICAgICAwP//AIWEUARAQoCAgICAgOD//wAgAiABIAOFIAIgBIVCgICAgICAgICAf4WEUCIFGyEEQgAgASAFGyEDDAILIAMgCUKAgICAgIDA//8AhYRQDQEgASAKhFAEQCADIAmEQgBSDQIgASADgyEDIAIgBIMhBAwCCyADIAmEUEUNACABIQMgAiEEDAELIAMgASABIANUIAkgClYgCSAKURsiCBshCiAEIAIgCBsiDEL/////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/wBWGwsQTgtTAQF/IAAoAhAiBEEQaiABIAIgBCgCCBEBACIBIAJFckUEQCAAEHAgAQ8LIAMEQCADIAEgACgCECgCDBEFACIAIAJrIgJBACAAIAJPGzYCAAsgAQsNACAAQQAgAUEAEJoDC/kBAgN+An8jAEEQayIFJAACfiABvSIEQv///////////wCDIgJCgICAgICAgAh9Qv/////////v/wBYBEAgAkI8hiEDIAJCBIhCgICAgICAgIA8fAwBCyACQoCAgICAgID4/wBaBEAgBEI8hiEDIARCBIhCgICAgICAwP//AIQMAQsgAlAEQEIADAELIAUgAkIAIAKnZ0EgaiACQiCIp2cgAkKAgICAEFQbIgZBMWoQYiAFKQMAIQMgBSkDCEKAgICAgIDAAIVBjPgAIAZrrUIwhoQLIQIgACADNwMAIAAgAiAEQoCAgICAgICAgH+DhDcDCCAFQRBqJAALKgEBfyMAQRBrIgMkACADIAI2AgwgACABIAJBpANBABCUBBogA0EQaiQAC0cAIAAgAUkEQCAAIAEgAhAeGg8LIAIEQCAAIAJqIQAgASACaiEBA0AgAEEBayIAIAFBAWsiAS0AADoAACACQQFrIgINAAsLCyABAX4gACAAIAIgASADQQRBABCCASIFIAEgBBC/ASAFC4sMAQZ/IwBBIGsiAyQAAkACQAJAAkACQAJ/IAAoAhAiAkGDf0cEQEEAIAJBV0cNARogACgCQCIELQBsQQFxRQRAIABBl+AAQQAQEwwDCyAEKAJkRQRAIABB6jtBABATDAMLQX8hBSAAEA8NBQJAAkACQAJAIAAoAhAiBEEpaw4EAgEBAgALIARB3QBGIARBOmtBAklyIARB/QBGcg0BCyAAKAIwDQBBACECIARBKkYEQCAAEA8NCEEBIQILIAAgARCtAUUNAQwHCyAAQQYQDUEAIQILIAAoAkAtAGwhASACBEAgABAtIQUgABAtIQIgAEGAAUH/ACABQQNGGxANIABBDhANIABBBhANIABBBhANIAAgBRAaIABBhgEQDSABQQNHIgdFBEAgAEGMARANCyAAQYMBEA0gAEHCABANIABB6gAQFyAAQesAQX8QGCEGIAAgAhAaQYoBIQQgACAHBH9BigEFIABBwQAQDSAAQcEAEBdBiwELEA0gAEEREA0gAEHrAEF/EBghBCAA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AqcQvAJFIQQMBgsgAacgAqdGIAVBeEZxIQQMBQsgBUF/Rw0EIAGnIAKnRiEEDAQLIAGntyEIIAVBB0cEQCAFDQQgAqe3DAILIAJCgICAgMCBgPz/AHy/DAELIAFCgICAgMCBgPz/AHy/IQggBQRAIAVBB0cNAyACQoCAgIDAgYD8/wB8vwwBCyACp7cLIQkCQCADBEACQAJAIAi9IgFC////////////AIMiAkKBgICAgICA+P8AWgRAIAm9Qv///////////wCDQoGAgICAgID4/wBUIQQMAQsgCb0iCkL///////////8Ag0KBgICAgICA+P8AVA0BCyAEIAJCgICAgICAgPj/AFZzIQQMBQsgA0ECRw0BCyAIIAlhIQQMAwsgASAKUSEEDAILIAVBdkcNACAAIAdBHGoiBiABEK0CIgMgACAHQQhqIAIQrQIiBRC9AiEEIAMgBkYEQCAGEBkLIAUgB0EIaiIDRw0AIAMQGQsgACABEAwgACACEAwLIAdBMGokACAECy8BAX8jAEHQAGsiAyQAIAMgACADQRBqIAEQgQE2AgAgACACIAMQEiADQdAAaiQACw0AIAAgASABED0QnQMLHQEBfyAAIAFB/wFxEA4gACgCBCEDIAAgAhAbIAMLEgAgACABIAIgAyAEQZQDELEDC1IBAX8gACgCDCIDRQRAQQAPCyAAIAAoAghB/////wNBgYCAgHwgASABQYGAgIB8TBsiASABQf////8DThtqNgIIIABB/////wMgAiADQQAQ3AILHwEBfyAAKAIMIgNFBEBBAA8LIAAgASACIANBABDcAgsgACABQgA3AgwgAUKAgICAgICAgIB/NwIEIAEgADYCAAtmAQF/An9BACAAKAIIIgIgAU8NABpBfyAAKAIMDQAaIAAoAhQgACgCACACQQNsQQF2IgIgASABIAJJGyIBIAAoAhARAQAiAkUEQCAAQQE2AgxBfw8LIAAgATYCCCAAIAI2AgBBAAsLZwECfwJAIAFCgICAgHBUDQAgAaciAy8BBkEEayIEQR1LQQEgBHRBz4CAgAJxRXINACAAIAMpAyAQDCADIAI3AyAPCyAAIAIQDCABQoCAgIBwg0KAgICA4ABSBEAgAEHu0gBBABASCwshAQF/IAAgASAAIAIQtgEiAiADIAQQFSEFIAAgAhAQIAULRwIBfgF/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PEdxRQRAIAAgBigCNBCeAQsgACAEEBoLIAAgBigCMCAGKAIsIAYoAjQgBigCPEEBIAwQwQELIAAoAhBB3QBGDQAgB0Glf0YEQEGQ0wAhCAwECyAAQSwQKEUNAQwFCwsgAEGFARANIAAoAkAiASABKAKwAigCADYCsAIgABAPDQMLAkAgBUUNACAAKAIQQT1HDQBBfyEHIABB7ABBfxAYIQEgABAPDQQgACAKEBogAwRAIABBDhANCyAAEFMNBCAAQewAIAsQGBogACABEBpBASEHDAQLIANFBEAgAEHDPUEAEBMMAwsgACgCQCgCgAIgDWpBswEgDiANaxAsGiAAKAJAKAKkAiAKQRRsaiIAIAAoAgBBAWs2AgBBACEHDAMLIAAgCEEAEBMMAQsgACgCACAGKAI0EBALQX8hBwsgBkFAayQAIAcLKwAgACgCQCgCpAFBAE4EQCAAQQYQDSAAQdkAEA0gACAAKAJALwGkARAUCwsTACAAIAEgAiADIARBAEEAEN0BC6YBAQF/IwBBEGsiAyQAIAMgAjcDCAJAIAAgAUGHASABQQAQESICQoCAgIBwg0KAgICA4ABRDQAgACACEDUEQCAAIAIgAUEBIANBCGoQNiICQv////9vViACQoCAgICwf4NCgICAgCBRcg0BIAAgAhAMIABBpcEAQQAQEkKAgICA4AAhAgwBCyAAIAIQDCAAIAEgACADQQhqEIoFIQILIANBEGokACACC6MBAgN/AX4gAEEQaiECIAEoAgAiBEEBaiEDAkAgACkCBCIFQoCAgIAIg1BFBEAgAiAEQQF0ai8BACIAQYD4A3FBgLADRyADIAWnQf////8HcU5yDQEgAiADQQF0ai8BACICQYD4A3FBgLgDRw0BIABBCnRBgPg/cSACQf8HcXJBgIAEaiEAIARBAmohAwwBCyACIARqLQAAIQALIAEgAzYCACAACxIAIAFB2AFOBEAgACABEIYFCwthACAAIAEgAkKAgICACHxC/////w9YBH4gAkL/////D4MFQoCAgIDAfiACub0iAkKAgICAwIGA/P8AfSACQv///////////wCDQoCAgICAgID4/wBWGwsgAyAEQQdyEJQBCzkAIABB/wBNBEAgAEEDdkH8////AXFBsP8BaigCACAAdkEBcQ8LIABBfnFBjMAARiAAEJYGQQBHcgs1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QfD//wFxayIYJAAgBSEVIAYEQCAHIAQgByAIGyIIQQAgCEEAShsiCGsiCUEAIAcgCU8bIREDQAJAIAggCkYEQANAIAggEUYNAiAYIAhBA3RqQoCAgIAwNwMAIAhBAWohCAwACwALIAUgCkEDdCIJaikDACIBQiCIp0F1TwRAIAGnIhUgFSgCAEEBajYCAAsgCSAYaiABNwMAIBFBAWohESAKQQFqIQoMAQsLIA4gBzYCVCAYIRULIA4gFTYCQCAOIBggBkEDdGoiETYCREEAIQgDQCAIIBdHBEAgESAIQQN0akKAgICAMDcDACAIQQFqIQgMAQsLIBIoAhQhBiAOIBYoAowBNgIwIBYgDkEwaiIUNgKMASASKAIwIQkgESAXQQN0aiIIIRcLQQAMAQtBAQshBwNAAkACQAJAAkAgB0UEQCAEQQN0ISMgA0KAgICAcIMhOyARQQhqIRogEUEQaiEbIBFBGGohHCAVQQhqIR0gFUEQaiEeIBVBGGohHyAUQRhqISQgAkIgiKciIEF+cSElIANCIIinISYgBK0hOiADpyEhIA5BMGohJyAOQegAaiEiIAghBwJAA0ACQCAGQQFqIQxCgICAgDAhNQJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJA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AAsgCCABNwMQIAhBGGohBwzeAQsgCCAIQQhrIgYpAwA3AwAgCEEQaykDACIBQiCIp0F1TwRAIAGnIgcgBygCAEEBajYCAAsgBiABNwMAIAhBCGohBwzdAQsgCCAIQQhrIgYpAwAiATcDACAGIAhBEGsiBikDADcDACABQiCIp0F1TwRAIAGnIgcgBygCAEEBajYCAAsgBiABNwMAIAhBCGohBwzcAQsgCCAIQQhrIgYpAwAiATcDACAIQRBrIgcpAwAhNSAHIAhBGGsiBykDADcDACAGIDU3AwAgAUIgiKdBdU8EQCABpyIGIAYoAgBBAWo2AgALIAcgATcDACAIQQhqIQcM2wELIAggCEEIayIGKQMAIgE3AwAgCEEQayIHKQMAITUgByAIQRhrIgcpAwA3AwAgBiA1NwMAIAcgCEEgayIGKQMANwMAIAFCIIinQXVPBEAgAaciByAHKAIAQQFqNgIACyAGIAE3AwAgCEEIaiEHDNoBCyAIQRBrIgYpAwAhASAGIAhBGGsiBikDADcDACAGIAE3AwAM0wELIAhBGGsiBikDACEBIAYgCEEQayIGKQMANwMAIAhBCGsiBykDACE1IAcgATcDACAGIDU3AwAM0gELIAhBIGsiBikDACEBIAYgCEEYayIGKQMANwMAIAhBEGsiBykDACE1IAcgCEEIayIHKQMANwMAIAYgNTcDACAHIAE3AwAM0QELIAhBKGsiBikDACEBIAYgCEEgayIGKQMANwMAIAhBGGsiBykDACE1IAcgCEEQayIHKQMANwMAIAYgNTcDACAHIAhBCGsiBikDADcDACAGIAE3AwAM0AELIAhBCGsiBikDACEBIAYgCEEQayIGKQMANwMAIAhBGGsiBykDACE1IAcgATcDACAGIDU3AwAMzwELIAhBEGsiBikDACEBIAYgCEEYayIGKQMANwMAIAhBIGsiBykDACE1IAcgATcDACAGIDU3AwAMzgELIAhBEGsiBikDACEBIAYgCEEYayIGKQMANwMAIAhBIGsiBykDACE1IAcgCEEoayIHKQMANwMAIAYgNTcDACAHIAE3AwAMzQELIAhBCGsiBikDACEBIAYgCEEQayIGKQMANwMAIAYgATcDAAzMAQsgCEEgayIGKQMAIQEgBiAIQRBrIgYpAwA3AwAgCEEIayIHKQMAITUgByAIQRhr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xH4iAUIAUg0EIA0gD3JBAE4NBSALQoCAgIDA/v8DNwMADA0LIAtCgICAgMB+IA+3IA23o70iAUKAgICAwIGA/P8AfSABQv///////////wCDQoCAgICAgID4/wBWGzcDAAwMCyANQQBKIA9BAE5xRQRAIAsCfiAPtyANtxCZBCI8vSIBAn8gPJlEAAAAAAAA4EFjBEAgPKoMAQtBgICAgHgLIgq3vVEEQCAKrQwBC0KAgICAwH4gAUKAgICAwIGA/P8AfSABQv///////////wCDQoCAgICAgID4/wBWGws3AwAMDAsgDyANcK0hAQwCCyAPtyE8IAsCfgJ8IA23Ij29QoCAgICAgID4/wCDQoCAgICAgID4/wBRBEBEAAAAAAAA+H8gPJlEAAAAAAAA8D9hDQEaCyA8ID0QowMLIjy9IgECfyA8mUQAAAAAAADgQWMEQCA8qgwBC0GAgICAeAsiCre9UQRAIAqtDAELQoCAgIDAfiABQoCAgIDAgYD8/wB9IAFC////////////AINCgICAgICAgPj/AFYbCzcDAAwKCyA1xCABxH0hAQsgAUKAgICACHxC/////w9WDQEgASE2CyA2Qv////8PgwwBC0KAgICAwH4gAbm9IgFCgICAgMCBgPz/AH0gAUL///////////8Ag0KAgICAgICA+P8AVhsLNwMADAULIBBBdkcgD0F2R3FFBEAgCSAKIAsgNSABIAkoAhAoAqwCESMADQcMBQsgCSAHQQhqIDUQbQ0FIAkgByABEG0NBgsCQAJAAkACQCAKQZsBaw4GAAECBAUDBAsgBysDCCAHKwMAogwFCyAHKwMIIAcrAwCjDAQLIAcrAwggBysDABCZBAwDCyAHKwMIITwgBysDACI9vUKAgICAgICA+P8Ag0KAgICAgICA+P8AUQRARAAAAAAAAPh/IDyZRAAAAAAAAPA/YQ0DGgsgPCA9EKMDDAILEAEACyAHKwMIIAcrAwChCyE8IAtCgICAgMB+IDy9IgFCgICAgMCBgPz/AH0gAUL///////////8Ag0KAgICAgICA+P8AVhs3AwALQQAMAgsgCSABEAwLIAtCgICAgDA3AwAgDUKAgICAMDcDAEF/CyEwIAdBEGokACAwDUsgCEEIayEHDEcLIAhBBGsoAgAiB0UgB0EHa0FuSXINQCAIIQcgCSAIQY4BEOEBRQ1GDEoLAkACfCAIQQhrIgcpAwAiAUIgiKciCkUEQEQAAAAAAAAAgCABpyIGRQ0BGkQAAAAAAADgQSAGQYCAgIB4Rg0BGiAHQgAgAX1C/////w+DNwMADEILIApBB2tBbUsNASABQoCAgIDA/v8Dfb8LITwgB0KAgICAwH4gPL0iAUKAgICAwIGA/P8AfSABQv///////////wCDQoCAgICAgID4/wBWGzcDAAxACyAIIQcgCSAIQY0BEOEBRQ1FDEkLIAhBCGsiBykDACIBQv////8PViABQv////8HUXJFBEAgByABQgF8Qv////8PgzcDAAw/CyAIIQcgCSAIQZABEOEBRQ1EDEgLIAhBCGsiBykDACIBQv////8PViABQoCAgIAIUXJFBEAgByABQgF9Qv////8PgzcDAAw+CyAIIQcgCSAIQY8BEOEBRQ1DDEcLIAkgCEEIayIHKQMAEGUiAUKAgICAcINCgICAgOAAUQRAIAdCgICAgDA3AwAMRwsgByABNwMAIAFCIIinQXVPBEAgAaciByAHKAIAQQFqNgIACyAIIAE3AwAgCSAIQQhqIgcgCkECaxDhAUUNQgxGCyAGQQJqIQwgESAGLQABQQN0aiIHKQMAIgFC/////w9WIAFC/////wdRckUEQCAHIAFCAXxC/////w+DNwMADDwLIAFCIIinQXVPBEAgAaciCiAKKAIAQQFqNgIACyAOIAE3A2AgCSAiQZABEOEBDUUgCSAHIA4pA2AQHQw7CyAGQQJqIQwgESAGLQABQQN0aiIHKQMAIgFC/////w9WIAFCgICAgAhRckUEQCAHIAFCAX1C/////w+DNwMADDsLIAFCIIinQXVPBEAgAaciCiAKKAIAQQFqNgIACyAOIAE3A2AgCSAiQY8BEOEBDUQgCSAHIA4pA2AQHQw6CyAIQQhrIgcpAwAiAUL/////D1gEQCAHIAFC/////w+FNwMADDoLIAghByMAQRBrIgokAAJ/AkACQCAJIAhBCGsiCykDABBlIgFCgICAgHCDIjVCgICAgOAAUQ0AIDVCgICAgOB+UQRAIAkgC0GWASABIAkoAhAoAqgCER8ADQEMAgsgCSAKQQxqIAEQlQENACALIAo1AgxC/////w+FNwMADAELIAtCgICAgDA3AwBBfwwBC0EACyExIApBEGok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//8AgyIGQoCAgICAgMD//wBWIAZCgICAgICAwP//AFEbDQAgACAChCAFIAaEhFAEQEEADwsgASADg0IAWQRAQX8hBCAAIAJUIAEgA1MgASADURsNASAAIAKFIAEgA4WEQgBSDwtBfyEEIAAgAlYgASADVSABIANRGw0AIAAgAoUgASADhYRCAFIhBAsgBAuhAgEFfwNAAkACQAJAAkACfyACIAdMIgkgBCAGTHJFBEAgASAHQQJ0aigCACIIIAMgBkECdGooAgAiCUkEQCAIDAILIAggCUcNAyAGQQFqIQYgB0EBaiEHIAghCQwECyAJDQEgASAHQQJ0aigCAAshCSAHQQFqIQcMAgsgBCAGTA0CIAMgBkECdGooAgAhCQsgBkEBaiEGCwJ/AkACQAJAAkAgBQ4DAwABAgsgBiAHcUEBcQwDCyAGIAdzQQFxDAILEAEACyAGIAdyQQFxCyAAKAIAIghBAXFGDQEgACgCBCAITARAIAAgCEEBahDRAgRAQX8PCyAAKAIAIQgLIAAgCEEBajYCACAAKAIIIAhBAnRqIAk2AgAMAQsLIAAQmAZBAAvmAQAgAAJ/IAEoAggiAEH+////B04EQEEAIAJBAXENARpB/////wcgAEH+////B0cNARogASgCBEH/////B2oMAQtBACAAQQBMDQAaIABBH00EQEEAIAEoAhAgASgCDEECdGpBBGsoAgBBICAAa3YiAGsgACABKAIEGwwBCyACQQFxRQRAQf////8HIAEoAgRFDQEaQYCAgIB4IABBIEcNARogASgCECABKAIMQQJ0akEEaygCABpBgICAgHgMAQtBACABKAIQIAEoAgwiAiACQQV0IABrEHEiAGsgACABKAIEGws2AgALEgAgACABIAIgAyAEQZMDELEDCw4AIABBACABQRByELoBC58BAgR/An4gAzUCACEJA0AgAiAFRkUEQCAAIAVBAnQiB2ogBq0gASAHajUCACAJfnwiCj4CACAFQQFqIQUgCkIgiKchBgwBCwsgACACQQJ0IgdqIAY2AgBBASAEIARBAU0bIQRBASEFA0AgBCAFRkUEQCAAIAVBAnQiBmoiCCAHaiAIIAEgAiADIAZqKAIAEL0ENgIAIAVBAWohBQwBCwsLWgEFfyADQQAgA0EAShshBgNAIAUgBkcEQCAAIAVBAnQiA2ogASAD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gICAgOAAUg0AIAEhAgwBCwJAIAKnIgUpAgQiCkL/////B4NQDQAgAaciAykCBCELAkAgAygCAEEBRyAKIAuFQoCAgIAIg0IAUnINACADIAAoAhAoAgwRBQAgBSkCBCIKpyIEQf////8HcSIHIAMpAgQiC6ciBkH/////B3EiCGogBEEfdnQgBkEfdiIJQRFzakkNACAFQRBqIQYgA0EQaiEEIAkEQCAEIAhBAXRqIAYgB0EBdBAeGiADIAMpAgQiCiAFKQIEfEL/////B4MgCkKAgICAeIOENwIEDAILIAQgCGogBiAHEB4aIAMgAykCBCIKIAUpAgR8Qv////8HgyILIApCgICAgHiDhDcCBCAEIAunakEAOgAADAELAn4CQAJAIAunQf////8HcSAKp0H/////B3FqIgdBgICAgARPBEAgAEHkyABBABA6DAELIAAgByAKIAuEpyIGQR92EOkBIggNAQtCgICAgOAADAELIAhBEGohBAJAIAZBAE4EQCAEIANBEGogAygCBEH/////B3EQHiIEIAMoAgRB/////wdxaiAFQRBqIAUoAgRB/////wdxEB4aIAQgB2pBADoAAAwBCyAEIAMgAygCBEH/////B3EQkwUgBCADKAIEQQF0aiAFIAUoAgRB/////wdxEJMFCyAIrUKAgICAkH+ECyEKIAAgARAMDAELIAEhCgsgACACEAwgCgsPACAAIAFCgICAgDAQggILCwAgAEGfCUEAEBILjgIBA38jAEEQayIFJAAgBSAAOQMIIAUgAUEBayIHNgIAIAZBgAFB9t8AIAUQSBogAyAGLQAAQS1GNgIAIAQgBi0AAToAACABQQJOBEAgBEEBaiAGQQNqIAcQHhoLIAEgBGpBADoAACACIQkgASAGaiABQQFKakECaiEBA0AgASICQQFqIQEgAiwAACIDEI8GDQALQQEhBAJAAkACQCADQf8BcUEraw4DAQIAAgtBACEECyABLAAAIQMgASECC0EAIQEgA0EwayIDQQlNBEADQCABQQpsIANrIQEgAiwAASEIIAJBAWohAiAIQTBrIgNBCkkNAAsLIAlBACABayABIAQbQQFqNgIAIAVBEGokAAuADAIHfwV+IwBBoANrIgUkAAJAIAG9IgxCgICAgICAgPj/AINCgICAgICAgPj/AFEEQCAMQv//////////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QCAHqwwBC0EACyIDNgIcIAcgA7hhDQMMAQsgAwRAQX8hAyAAIAIQlgEiAkKAgICAcINCgICAgOAAUQ0EIAAgBEEcaiACQQEQvgJFDQMMBAsgACAEQRxqIAIQdQRAIAAgAhAMDAILQX8hAyAAIAIQlgEiAkKAgICAcINCgICAgOAAUQ0DIAAgBEEEaiACQQAQvgINAyAEKAIEIAQoAhxGDQILIABBiscAQQAQRAtBfyEDDAELIAEgBCgCHDYCAEEAIQMLIARBIGokACADC0ABAX4gABDiASICQoCAgIBwg0KAgICA4ABSBEAgAqdBBGogARCcAkUEQCACDwsgACACEAwgABBwC0KAgICA4AALMgEBfyMAQdAAayICJAAgAiAAIAJBEGogARCBATYCACAAQbzpACACEMMCIAJB0ABqJAALoAECAX8BfiMAQRBrIgUkACAFIAQ2AgxBfyEEIAAgASAFQQxqENMBRQRAIAMoAgAiAEF8cSABIAIgAygCBCAAQQNxQQJ0QYS3AWooAgARGwAhBiADEOAFIAUoAgwiACAAKAIAQf////8DcTYCACADQoCAgIAwIAYgBkKAgICAcINCgICAgOAAUSIAGzcDAEF/QQAgABshBAsgBUEQaiQAIAQLFQECfiAAIAEQ6AEhAyAAIAEQDCADCw0AIAAgASACQQIQyAIL1QEBA38jAEEQayIFJABBfyEDAkAgACgCFA0AAkACQCABQYCAgIAETgRAIAAoAgBB5MgAQQAQOgwBCyABIAAoAgxBA2xBAm0iBCABIARKGyEBIAAoAhAiBCACQYACSHJFBEAgACABEOADIQMMAwsgACgCACAAKAIEIAEgBHQgBGtBEWogBUEMahCnASICDQELIAAQ9wIMAQsgBSgCDCEDIAAgAjYCBCAAQf////8DIAMgACgCEHYgAWoiACAAQf////8DThs2AgxBACEDCyAFQRBqJAAgAwsqAQF/IAAoAhAiA0EQaiABIAIgAygCCBEBACIBIAJFckUEQCAAEHALIAELgQECAn8BfgJAIAEpAgQiBEL//////////79/VgRAIAEoAgwhAAwBCyAAKAI0IARCIIinIAAoAiRBAWtxQQJ0aiECIAAoAjghAwNAIAMgAigCACIAQQJ0aigCACICIAFGDQEgAkEMaiECIAANAAtBxocBQajsAEH/FEH4DhAAAAsgAAupBwIJfwF+AkACQAJAAn8gAkECTARAIAIgASkCBCIMQj6Ip0YEQCAAIAEQxgIiBEHXAUoNBSABIAEoAgBBAWs2AgAgBA8LIAAoAjQgACgCJEEBayABIAIQ6wVB/////wNxIgdxIgpBAnRqIQMgDKdB/////wdxIQUDQCACIAMoAgAiBEUNAhoCQCAAKAI4IARBAnRqKAIAIgMpAgQiDKdB/////wdxIAVHIAxCPoinIAJHciAMQiCIp0H/////A3EgB0dyDQAgAyABIAUQ6gUNACAEQdgBSA0EIAMgAygCAEEBajYCAAwECyADQQxqIQMMAAsACyACQQNHIQdBAwshBQJAIAAoAjwNAEEAIQQgAEEQaiILIAAoAjhB0wEgACgCLEEDbEECbSICIAJB0wFMGyICQQJ0IAAoAggRAQAiCEUNASAAKAIsIgkhAyAJRQRAIAtBECAAKAIAEQMAIgZFBEAgCyAIIAAoAgQRAAAMAwsgBkKAgICAgICAgEA3AgQgBkEBNgIAIAZBADYADCAIIAY2AgAgACAAKAIoQQFqNgIoQQEhAwsgACADNgI8IAAgCDYCOCAAIAI2AiwgCSACIAIgCUkbIQQgAkEBayEGA0AgAyAERg0BIAAoAjggA0ECdGpBASADQQFqIgJBAXRBAXIgAyAGRhs2AgAgAiEDDAALAAsCQCABBEAgASkCBCIMQv//////////P1gEQCABIAwgBa1CPoaENwIEDAILIABBEGogDKciAkEfdSACQf////8HcSACQR92dGpBEWogACgCABEDACICRQRAQQAhBAwECyACQQE2AgAgAiACKQIEQv////93gyABKQIEQoCAgIAIg4QiDDcCBCACIAxCgICAgHiDIAEpAgRC/////weDhDcCBCACQRBqIAFBEGogASgCBCIDQf////8HcSADQR92dCADQX9zQR92ahAeGiAAIAEQkAQgAiEBDAELIABBEGpBECAAKAIAEQMAIgFFBEBBAA8LIAFCgYCAgICAgICAfzcCAAsgACAAKAI4IAAoAjwiBEECdGoiAigCAEEBdjYCPCACIAE2AgAgASAENgIMIAEgATUCBCAHrUIghoQgBa1CPoaENwIEIAAgACgCKEEBajYCKCAFQQNGDQIgASAAKAI0IApBAnRqIgEoAgA2AgwgASAENgIAIAAo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QQAQEgwBCwJAIARFIAJBAExyRQRAIAAgBSAHQgAgAUF/EPMCDQIMAQsgASEICyACQQAgAkEAShutIQlCACEBA0AgASAJUgRAIAMgAadBA3RqKQMAIgdCIIinQXVPBEAgB6ciAiACKAIAQQFqNgIACyABIAh8IQogAUIBfCEBIAAgBSAKIAcQe0EATg0BDAILCyAAIAVBMCAGQoCAgIAIfCIIQv////8PWAR+IAZC/////w+DBUKAgICAwH4gBrm9IgFCgICAgMCBgPz/AH0gAUL///////////8Ag0KAgICAgICA+P8AVhsLEDlBAEgNACAAIAUQDCAGQv////8PgyAIQv////8PWA0BGkKAgICAwH4gBrm9IgFCgICAgMCBgPz/AH0gAUL///////////8Ag0KAgICAgICA+P8AVhsMAQsgACAFEAxCgICAgOAACyELIAxBEGokACALCxUBAn4gACABEIcFIQMgACABEAwgAwv5DgIKfgR/IwBBEGsiECQAIBAgAjcDCAJAAkACfgJAAkACQAJAAkACQAJAAkACQAJAQQcgAkIgiKciDiAOQQdrQW5JGyIOQQdqDg8EAwMDAwMABQUFAwMDAwECCwJAAkACQAJAIAKnIg4vAQYiD0EEaw4DAQACAwtCgICAgDAhByAAIAIQNCICQoCAgIBwg0KAgICA4ABRDQsgACACEO4DIgJCgICAgHCDQoCAgIDgAFENCyABKAIoIAIQhAEhDgwOC0KAgICAMCEHIAAgAhCWASICQoCAgIBwg0KAgICA4ABRDQogASgCKCACEIQBIQ4MDQsgASgCKCAOKQMgEI0BIQ4gACACEAwMDAsgD0EhRg0HQoCAgIAwIQYgACABKQMIQQEgEEEIahDxAyIEQoCAgIDwAINCgICAgOAAUQ0GIAAgBBAnBEAgAEHJ3wBBABASDAcLIANCIIinQXVPBEAgA6ciDiAOKAIAQQFqNgIACyABKQMYIgRCIIinQXVPBEAgBKciDiAOKAIAQQFqNgIACwJAAkACQAJAIAAgAyAEELYCIghCgICAgHCDQoCAgIDgAFEEQEKAgICAMCEHDAELIAEpAxgiBEKAgICAcINCgICAgJB/UQRAIASnKAIEQf////8HcUUNAwsgCEIgiKdBdU8EQCAIpyIOIA4oAgBBAWo2AgALIABB65YBIAhB7JYB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BEAgAiAANgIAC0EBC4cDAgN+BH8CQCABKAIIIgZB/v///wdOBEBBASEHIAJBAXENAUL///////////8AIQMgBkH+////B0cNASABNAIEQv///////////wB8IQMMAQsgBkEATARADAELIAZBP00EQCABKAIQIAEoAgwiCEECdGoiCUEEaygCACECQgAgBkEgTQR+IAJBICAGa3atBSAIQQJPBH4gCUEIazUCAAVCAAsgAq1CIIaEQcAAIAZrrYgLIgN9IAMgASgCBBshAwwBCyACQQFxRQRAIAEoAgRFBEBC////////////ACEDQQEhBwwCC0KAgICAgICAgIB/IQNBASEHIAZBwABHDQEgASgCECABKAIMIgFBAnRqIgJBBGs1AgBCIIYhBCABQQJPBH4gAkEIazUCAAVCAAsgBIRCgICAgICAgICAf1IhBwwBC0IAIAEoAhAiCCABKAIMIgIgAkEFdCAGayIGEHGtIAggAiAGQSBqEHGtQiCGhCIDfSADIAEoAgQbIQMLIAAgAzcDACAHC60CAgJ/An4jAEEgayICJAACQCAAKAIIQf////8HRgRAQoCAgICAgID8/wAhBAwBCyAAKAIAIQMgAkIANwIYIAJCgICAgICAgICAfzcCECACIAM2AgwgAkEMaiIDIAAQSRoCfiACKAIUIgBB/f///wdMBEAgA0E1QcgEELoBGiACKAIUIQALQoCAgICAgID4/wAgAEH+////B0YNABpCACAAQYCAgIB4Rg0AGiACKAIcIQMCfiACKAIYQQJGBEAgAykCAAwBCyADNQIAQiCGCyEEIABBgnhMBEAgBEGOeCAAa62IIQRCAAwBCyAEQguIQv////////8HgyEEIABB/gdqrUI0hgshBSAEIAWEIAI1AhBCP4aEIQQgAkEMahAZCyABIAQ3AwAgAkEgaiQACw0AIAAgASACQQIQsAMLIwACQAJAAkAgAg4CAAECCyAAIAFyDwsgACABcw8LIAAgAXEL4QgBEX8gAigCBCAFcyIFIAEoAgQiBnMhDQJAIAEgAhDyASIIIA1Fcg0AIAEoAghB/f///wdKDQAgACAEQQdxQQJGEIABQQAPCyAFIAYgCEEASCIGGyEFIAEgAiAGGyEKAkACQAJAIAIgASAGGyIIKAIMIgcEQCAKKAIMIgsNAQsgCCgCCCIBQf7///8H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CyAAIAsQDCAAIAgQDCAAIAoQDCAAIAEQDAwBCyABIQ0LIAVBIGokACANC0sBAn8gACABRwRAIAAoAhAiAgRAIAAoAgAiAygCACACQQAgAygCBBEBABoLIAAgASkCADcCACAAIAEoAhA2AhAgACABKQIINwIICwv0AQIDfgF/AkAgAykDACIEQoCAgIBwWgRAIAMpAwgiBUL/////b1YNAQsgABAiQoCAgIDgAA8LQoCAgIDgACEGIABCgICAgCBBLBBHIgFCgICAgHCDQoCAgIDgAFIEfiAAQRgQJCICRQRAIAAgARAMQoCAgIDgAA8LIASnIgMgAygCAEEBajYCACACIAQ3AwAgBaciByAHKAIAQQFqNgIAIAIgBTcDCCAAIAQQNSEAIAJBADoAESACIAA6ABAgAUKAgICAcFoEQCABpyIAIAI2AiAgACAALQAFQe8BcSADLQAFQRBxcjoABQsgAQVCgICAgOAACwsbACAAEBkgAEIANwIQIABCADcCCCAAQgA3AgALCQAgASACEPgFCxMAIABBEGogASACIAAoAggRAQALqAECAX8CfiAAvSIEQv///////////wCDQoGAgICAgID4/wBaBEAgAb1C////////////AINCgYCAgICAgPj/AFQPC0F/IQICQCAAIAFjDQAgAb0iA0L///////////8Ag0KAgICAgICA+P8AVg0AQQEhAiAAIAFkDQBBACECIABEAAAAAAAAAABiDQAgBEIAUwRAIANCP4enQX9zDwsgA0I/iKchAgsgAgvKBQIFfwN+IwBBMGsiAiQAIAIgATcDECACQQA2AgwgAiAANgIIIAIgAykDACIKNwMYAkACQCAKQoCAgIBwgyILQoCAgIAwUgRAQoCAgIDgACEJIAAgChBVDQELQoCAgIDgACEJIAAgARCKASIFQQBIDQACQCAFQQJJDQAgAaciAy8BBkEVayIEQf//A3FBC08NAiACIARBAnRB/P8PcSIEQZz1AWooAgA2AiBBASADLwEGQcqeAWotAAAiBnQhCCADKAIkIQcgC0KAgICAMFIEQCAAIAVBAnQQJCIERQ0CQQAhAwNAIAMgBUZFBEAgBCADQQJ0aiADNgIAIANBAWohAwwBCwsgAiAINgIoIAIgBzYCJCAEIAVBBEHLACACQQhqENcBAkACQAJAAkAgAigCDA4CAAEDCyAAIAUgBnQiAxAkIgYNAQsgACgCECIAQRBqIAQgACgCBBEAAAwECyAGIAcgAxAeIQZBACEDAkACQAJAAkACQCAIQQFrDggAAQkCCQkJAwkLA0AgAyAFRg0EIAMgB2ogBiAEIANBAnRqKAIAai0AADoAACADQQFqIQMMAAsACwNAIAMgBUYNAyAHIANBAXRqIAYgBCADQQJ0aigCAEEBdGovAQA7AQAgA0EBaiEDDAALAAsDQCADIAVGDQIgByADQQJ0IghqIAYgBCAIaigCAEECdGooAgA2AgAgA0EBaiEDDAALAAsDQCADIAVGDQEgByADQQN0aiAGIAQgA0ECdGooAgBBA3RqKQMANwMAIANBAWohAwwACwALIAAoAhAiA0EQaiAGIAMoAgQRAAALIAAoAhAiAEEQaiAEIAAoAgQRAAAMAQsgByAFIAggBEHI9QFqKAIAIAJBCGoQ1wEgAigCDA0BCyABQiCIp0F1TwRAIAGnIgAgACgCAEEBajYCAAsgASEJCyACQTBqJAAgCQ8LEAEAC+cCAQF+IAAgARCKASICQQBIBEBCgICAgOAADwsCQCACRQ0AAkACQAJAAkACQCABpyIALwEGQcqeAWotAAAOBAABAgMECyAAKAIkIgAgAmohAgNAIAAgAkEBayICTw0FIAAtAAAhAyAAIAItAAA6AAAgAiADOgAAIABBAWohAAwACwALIAAoAiQiACACQQF0aiECA0AgACACQQJrIgJPDQQgAC8BACEDIAAgAi8BADsBACACIAM7AQAgAEECaiEADAALAAsgACgCJCIAIAJBAnRqIQIDQCAAIAJBBGsiAk8NAyAAKAIAIQMgACACKAIANgIAIAIgAzYCACAAQQRqIQAMAAsACyAAKAIkIgAgAkEDdGohAgNAIAAgAkEIayICTw0CIAApAwAhBCAAIAIpAwA3AwAgAiAENwMAIABBCGohAAwACwALEAEACyABQiCIp0F1TwRAIAGnIgAgACgCAEEBajYCAAsgAQtRAgF/AX5CgICAgOAAIQQgACABIAIQayIDBH4gAygCICIDKAIMKAIgLQAEBEAgAkUEQEIADwsgABBfQoCAgIDgAA8LIAM1AhAFQoCAgIDgAAsLNwAgACABIAIQayIARQRAQoCAgIDgAA8LIAAoAiAoAgwiACAAKAIAQQFqNgIAIACtQoCAgIBwhAsMACAAKAIQIAEQ5wML2gEBAn4CQAJAIAJFBEAgAUKAgICAcIMhBSAAQS8QKSEEDAELAn4gAUKAgICAcIMiBUKAgICAMFIgAykDACIEQoCAgIBwg0KAgICAgH9SckUEQCAAQbmMASAAIAAoAhAgBKcQxgIQKUGrjAEQsgEMAQsgACAEECULIgRCgICAgHCDQoCAgIDgAFENAQsgBUKAgICAMFENACAAIAFBBRBeIgFCgICAgHCDQoCAgIDgAFIEQCAAIAEgBBC9ASAAIAFBMCAEpykCBEL/////B4NBABAVGgsgASEECyAEC0YBAX8CQCAAKAIIIAJqIgMgACgCDEoEQCAAIAMgARDEAg0BCwNAIAJBAEwEQEEADwsgAkEBayECIAAgARCHAUUNAAsLQX8LlQECBX8BfiABKQIEIginQf////8HcSIDRQRAIAIPCyAAKAIEQf////8HcSEHAn8gCEKAgICACINQRQRAIAEvARAMAQsgAS0AEAshBSADQQFrIQYgByADayEEAkADQCACIARKDQEgACAFIAIQoAEiA0EASCADIARKcg0BIAAgASADQQFqIgJBASAGELwDDQALIAMPC0F/C6cBAgN/AX4CQAJAIAAgARD2AyIDQQBIDQAgA0UNAUGbHiECIAAgACABQe4AIAFBABARIgVCgICAgHCDIgFCgICAgCBRIAFCgICAgDBRcgR/QZseBSABQoCAgIDgAFENASAAIAUQNCIBQoCAgIBwg0KAgICA4ABRDQFBACECIAGnQecAQQAQoAEhBCAAIAEQDCAEQQBODQJB2ssAC0EAEBILQX8hAgsgAguhAQIDfwF+AkACQCAAKQIEIgRCgICAgAiDUA0AIABBEGohAiAEp0H/////B3EhA0EAIQADQCAAIANODQECQCACIABBAXRqLwEAIgFBgPADcUGAsANHBEAgACEBDAELIAFB/7cDSw0DIABBAWoiASADTg0DIAIgAUEBdGovAQBBgEBrQf//A3FBgPgDSQ0DCyABQQFqIQAMAAsAC0F/IQALIAALVQEBfwJAAkACQCABQiCIp0EBag4DAAECAQsgAaciAi8BBkEGRw0AIAIpAyAiAUKAgICAcINCgICAgBBRDQELIABBlMAAQQAQEkKAgICA4AAhAQsgAQsQAEHOkQEgAEELEJICQQBHC4kB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ADcCECAAQRBqIAIgACgCBBEAAAwBCyACQoCAgIAwNwMoIAJCgICAgDA3AyAgAkEBNgIECyABIAEoAgxBAWs2AgwLC4YBACAAIAEgBEEiahBaIgJFBEBCgICAgOAADwsgACACIAMpAwAiAUIAIAFCIIinQQdrQW5PGyABIAFCgICAgMCBgPz/AHxC////////////AINQGxDyAiIARQRAQoCAgIAwDwsgACkDKCIBQiCIp0F1TwRAIAGnIgAgACgCAEEBajYCAAsgAQu7BQIDfgd/IwBBEGsiCyQAQoCAgIDgACEHAkAgACABIARBImoQWiICRQ0AIAIoAgBFIAMpAwAiBUIAIAVCIIinQQdrQW5PGyAFIAVCgICAgMCBgPz/AHxC////////////AINQGyIFQv////9vVnJFBEAgABAiDAELQoCAgIAwIQYgBEEBcUUEQCADKQMIIQYLAkAgACACIAUQ8gIiAwRAIAAgAykDKBAMDAELIABBMBAkIgNFDQEgAyACNgIIIANCATcDAAJAIAIoAgAEQCADIAWnIgQoAhg2AgwgBCADNgIYDAELIAVCIIinQXVJDQAgBaciBCAEKAIAQQFqNgIACyADIAU3AyAgAigCECIJIAIoAhQiBEEBayAFENkDcUEDdGoiCCgCACIKIANBGGoiDDYCBCADIAg2AhwgAyAKNgIYIAggDDYCACACKAIEIgggA0EQaiIKNgIEIAMgAkEEaiIMNgIUIAMgCDYCECACIAo2AgQgAiACKAIMQQFqIgg2AgwgCCACKAIYSQ0AIAAgCUEEIARBAXQgBEEBRhsiAEEDdCALQQxqEKcBIghFDQAgCygCDEEDdiAAaiEEQQAhAANAIAAgBEZFBEAgCCAAQQN0aiIJIAk2AgQgCSAJNgIAIABBAWohAAwBCwsgBEEBayEKIAJBCGohAANAIAwgACgCACIARwRAIABBDGsoAgBFBEAgCCAAKQMQENkDIApxQQN0aiIJKAIAIg0gAEEIaiIONgIEIAAgCTYCDCAAIA02AgggCSAONgIACyAAQQRqIQAMAQsLIAIgBDYCFCACIAg2AhAgAiAEQQF0NgIYCyAGQiCIp0F1TwRAIAanIgAgACgCAEEBajYCAAsgAyAGNwMoIAFCIIinQXVPBEAgAaciACAAKAIAQQFqNgIACyABIQcLIAtBEGok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AmoQI0UNDAJAIAMoAqgGIgVBAEgEQCADKALYBiEFDAELIAMgBTYC2AYLIAEgAygCxAYgBRAuIANBwAZqQfIBEA4gAygCrAZBAXMhBQwSCyADQX82AogDIANCw/aAgOABNwOAAyADQZwGaiAEIANBgANqECNFDQsCQCADKAKoBiICQQBIBEAgAygC2AYhAgwBCyADIAI2AtgGCyABIAMoAsQGIAIQLiADQcAGaiICIAMtAKwGEA4gAiADKAK8BhAbDBALIANBfzYCuAMgA0LZuP2CcDcDsAMgA0GcBmogBCADQbADahAjRQ0KIAMoAqgGIgJBAE4EQCADIAI2AtgGCyADQo6AgIBwNwOgAyADKAKsBiIFQQFqIQYCQCADQZwGaiADKAKkBiICIANBoANqECMEfyADKAKoBiICQQBOBEAgAyACNgLYBgsgAyADKAKwBjYClANBfyEEIANBfzYCmAMgAyAFQQFrNgKQAyADQZwGaiADKAKkBiICIANBkANqECNFDQEgAygCpAYhAiADKAKoBgVBfwshBCAGIQULIAEgAygCxAYgAygC2AYQLiADQcAGaiAFIAMoArAGEFkgBEEASA0TIAMgBDYC2AYMEwsgBi8AASICQf8BSw0JIANCjoCAgHA3AswEIAMgAjYCyAQgA0KRpYKAkAs3A8AEAkAgA0GcBmoiBiAEIANBwARqECNFBEAgA0KOgICAcDcDsAQgAyACNgKsBCADQdkANgKoBCADQo+hgoCQAjcDoAQgBiAEIANBoARqECNFDQELAkAgAygCqAYiBUEASARAIAMoAtgGIQUMAQsgAyAFNgLYBgsgASADKALEBiAFEC4gA0HABmoiBEGUAUGTASADKAKsBkF9cUGQAUYbEA4gBCACQf8BcRAODA8LIANCjoCAgHA3ApQEIAMgAjYCkAQgA0KRgICAkAs3A4gEIANChICAgOATNwOABCADQZwGaiAEIANBgARqECMEQAJAIAMoAqgGIgVBAEgEQCADKALYBiEFDAELIAMgBTYC2AYLIAEgAygCxAYgBRAuAkAgAygCvAZBL0YEQCADQcAGakHBARAODAELIANBwAZqIgRBBBAOIAQgAygCvAYQGwsgA0HABmoiBEGVARAOIAQgAkH/AXEQDgwPCyADQo6AgIBwNwL0AyADIAI2AvADIANCkYCAgJALNwPoAyADQoGAgIDgEzcD4AMgA0GcBmogBCADQeADahAjBEACQCADKAKoBiIFQQBIBEAgAygC2AYhBQwBCyADIAU2AtgGCyABIAMoAsQGIAUQLiADQcAGaiIEIAMoArQGEM4DIARBlQEQDiAEIAJB/wFxEA4MDwsgA0KOgICAcDcD2AMgAyACNgLUAyADQdkANgLQAyADQp6BgICQAjcDyAMgA0LYtvmCcDcDwAMgA0GcBmogBCADQcADahAjBEACQCADKAKoBiIFQQBIBEAgAygC2AYhBQwBCyADIAU2AtgGCyABIAMoAsQGIAUQLiADQcAGaiIEIAMoAqwGIAMoArAGEFkgBEGVARAOIAQgAkH/AXEQDgwPCyABIAMoAsQGIAMoAtgGEC4gA0HABmpB2AAgAhBZIAQhAgwSCyAGLwABIQIgASADKALEBiADKALYBhAuIANBwAZqIAUgAhBZIAQhAgwRCyADIAYvAAEiAjYC5AQgA0F/NgLoBCADIAVBAWs2AuAEIANBnAZqIAQgA0HgBGoQIwRAAkAgAygCqAYiBEEASARAIAMoAtgGIQQMAQsgAyAENgLYBgsgASADKALEBiAEEC4gA0HABmogBUEBaiACEFkMDQsgASADKALEBiADKALYBhAuIANBwAZqIAUgAhBZIAQhAgwQCyABIAogCCAEIANB2AZqEKUCIQQMBgsgASgC1AIhCyABKALMAiEGQQAhCUEAIQgDQAJAIAkgC0gEQEEDIQogBigCACICQeoAa0EDTwRAIAJB7QFHDQJBASEKCwJAIAEoAqQCIAYoAgxBFGxqKAIMIAYoAggiBWsiBEGAf0ggBCAKQf8AakpyRQRAIAZBATYCBCACQe0BRgRAQewBIQIgBkHsATYCAAwCCyAGIAJBgAFqIgI2AgAMAQsgAkHsAEcgBEGAgAJqQf//A0tyDQIgBkLtgYCAIDcCAEECIQpB7QEhAgsgAygCwAYgBWpBAWsgAjoAACAGKAIEIgIgAygCwAYgBWpqIgQgBCAKaiADKALEBiAFIApqIAJqaxCrASADIAMoAsQGIAprNgLEBkEAIQQgASgCrAIiAkEAIAJBAEobIQcgASgCpAIhAgNAIAQgB0YEQCABKALUAiELIAYhByAJIQQDQAJAIAsgBEEBaiIETARAQQAhAiABKALgAiIEQQAgBEEAShshBANAIAIgBEYNAiAFIAEoAtgCIAJBA3RqIgcoAgAiDEkEQCAHIAwgCms2AgALIAJBAWohAgwACwALIAciAkEQaiEHIAIoAhgiDCAFTA0BIAIgDCAKazYCGAwBCwsgCEEBaiEIDAMLIAUgAigCDCILSARAIAIgCyAKazYCDAsgAkEUaiECIARBAWohBAwACwALIAEoAswCIQIgCARAQQAhBQNAIAUgC0gEQCABKAKkAiACKAIMQRRsaigCDCACKAIIIgRrIQYCQAJAAkACQCACKAIEQQFrDgQAAQMCAwsgAygCwAYgBGogBjoAACABKALUAiELDAILIAMoAsAGIARqIAY7AAAMAQsgAygCwAYgBGogBjYAAAsgAkEQaiECIAVBAWohBQwBCwsgASgCzAIhAgsgACgCECIEQRBqIAIgBCgCBBEAACABQQA2AswCIAAoAhAiAkEQaiABKAKkAiACKAIEEQAAIAFBADYCpAIgASgC2AIhAgJAIAEtAG5BAnEEQCACIQUMAQtBACEFIAJFDQAgASgC8AIhByABKAIAIAFB9AJqIggQgwJBACECQQAhCgNAIAEoAtgCIQUgAiABKALgAk4NAQJAIAUgAkEDdGoiBigCBCIEQQBIIAQgB0ZyDQAgBigCACIGIAprIgVBAEgNAAJAIAQgB2siB0EBaiIKQQRLIAVBMktyRQRAIAggCiAFQQVsakEBakH/AXEQDgwBCyAIQQAQDiAIIAUQsQUgCCAHQQF0IAdBH3VzELEFCyAGIQogBCEHCyACQQFqIQIMAAsACyAAKAIQIgJBEGogBSACKAIEEQAAIAFBADYC2AIgDRCJASANIAMpAtAGNwIQIA0gAykCyAY3AgggDSADKQLABjcCACABQQE2AqACIAEoAowCBEAgABBwDCALIAEoAoACIQcgAyABKAKEAiIENgKcBiADIAAgBEEBdBAkIgY2AqQGIAZFDR9BACECIARBACAEQQBKGyEFA0AgAiAFRwRAIAYgAkEBdGpB//8DOwEAIAJBAWohAgwBCwsgA0EANgKsBiADIAAgBEECdBAkIgI2AqgGAkAgAkUNACADQgA3ArAGIANBADYCoAYgACADQZwGakEAQQBBAEF/ELABDQADQCADKAKsBiECAkACQAJAIAMoArAGIgRBAEoEQCADIARBAWsiBDYCsAYgByACIARBAnRq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IAIgCTYCSCACIAo2AkQgAkHBAEHQACAHQQxIGzYCTCACIAdBC2pBDG9BAWo2AkAgAkGQAmogA2pBwAAgA2tB5vQAIAJBQGsQSCADaiEDCyAAIAJBkAJqIAMQ6gEhEQsgAkHQAmokACARCzcCA38BfiMAQRBrIgAkACAAEI0GIAApAwAhAyAAKAIIIQIgAEEQaiQAIAJB6AdtrCADQugHfnwLhwEBAXwgACADKQMAEKgBIgJFBEBCgICAgOAADwsgAhAHIQQgACACEDEgBL0iAQJ/IASZRAAAAAAAAOBBYwRAIASqDAELQYCAgIB4CyIAt71RBEAgAK0PC0KAgICAwH4gAUKAgICAwIGA/P8AfSABQv///////////wCDQoCAgICAgID4/wBWGwvxAQIGfwF+IABBCBAkIgRFBEBBfw8LIARCATcCACACpyEGIAJCIIinQXVJIQgDQAJAAkAgA0ECRg0AIAAgACkDMCADQS5yEEciCUKAgICAcINCgICAgOAAUgRAIABBEBAkIgUNAiAAIAkQDAtBfyEHIANFDQAgACABKQMAEAwLIAAoAhAgBBD/BCAHDwsgBCAEKAIAQQFqNgIAIAUgBDYCCCAIRQRAIAYgBigCAEEBajYCAAsgBSACNwMAIAlCgICAgHBaBEAgCacgBTYCIAsgACAJQS9BARCYAyABIANBA3RqIAk3AwAgA0EBaiEDDAALAAt/AQV/IABBEGohBCABQQxqIQUgASgCECECA0AgAiAFRkUEQCACKAIEIQYgACACKQMQECEgACACKQMYECEgACACKQMgECEgACACKQMoECEgBCACIAAoAgQRAAAgBiECDAELCyABKAIIIgMEQCAAIAMQzgELIAQgASAAKAIEEQAAC+EDAgR/An4jAEFAaiICJAAgAiAAIAEQsQIiBjcDOAJAAkAgASgCIARAIAZCgICAgHCDQoCAgIDgAFENASAAIAEpAyhCgICAgDBBASACQThqEBwhBiAAIAIpAzgQDCAAIAYQDAwCCyACIAEoAmRBCGsiAykDADcDKCADQoCAgIAwNwMAIAAgBhAMQQAhAyAAIAApA1AgACACQShqQQAQ3gEhBiAAIAIpAygQDCAGQoCAgIBwg0KAgICA4ABRDQADQAJAIANBAkcEQCACQRBqIANBA3RqIAAgACkDMCADQTFqEEciBzcD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aiIGKAIEIAJBABARIgNCgICAgHCDQoCAgIDgAFENAyAGKAIEIQYCfyAEBEAgACABIAYgAxA5DAELIAAgASAGIANBBxAVC0EASA0DCyAFQQFqIQUMAQsLIAAgCCALEFtBACEJDAELIAAgCCALEFsLIAdBMGokACAJC6YBAQF+AkACQAJ+IARBBHEEQEEpIQIgACABEEoMAQtBKCECIAAgARAgCyIBQoCAgIBwg0KAgICA4ABRDQAgACACEIYBIgVCgICAgHCDQoCAgIDgAFENACAAQRAQJCICBEAgAkEANgIMIAIgBEEDcTYCCCACIAE3AwAgBUKAgICAcFQNAiAFpyACNgIgDAILIAAgBRAMCyAAIAEQDEKAgICA4AAPCyAFC8QBAQR/IAGnIgUgAjYCICAFQgA3AiQCQCACKAI8IgZFDQACQCAAIAZBAnQQXCIIRQ0AIAUgCDYCJEEAIQUDQCAFIAIoAjxODQIgAigCJCAFQQN0aiIHLwECIQYCQCAHLQAAIgdBAXEEQCAAIAQgBiAHQQF2QQFxEP8DIgYNAQwDCyADIAZBAnRqKAIAIgYgBigCAEEBajYCAAsgCCAFQQJ0aiAGNgIAIAVBAWohBQwACwALIAAgARAMQoCAgIDgACEBCyABC4IBAQJ+IAAgARApIQICQCABQQBIDQAgACgCECgCOCABQQJ0aigCACkCBCIDp0GAgICAeEYgA0KAgICA8P///z+DUCADQv//////////v39WcSADQoCAgICAgICAQINCgICAgICAgICAf1FyRXINACAAQa/wACACQa3wABCyASECCyACC2QBAn8CQAJAIAFCgICAgHBUDQAgARCUBQ0AQX8hAyAAIAIQMCIERQ0BIAAgBBDEBSECIAAgBBAQIAJCgICAgHCDQoCAgIDgAFENASAAIAFBNyACQQEQFUEASA0BC0EAIQMLIAMLNQACQCACRSABQoCAgIBwVHINACABEJQFDQAgACABQTcgACACEClBARAVQQBODQBBfw8LQQALDAAgACABQbYVELUBC2gCAX8BfgJAIAAgAUHqACABQQAQESIEQoCAgIBwg0KAgICA4ABSBEAgACAEECchAyAAIAFBwQAgAUEAEBEiAUKAgICAcINCgICAgOAAUg0BC0EAIQNCgICAgOAAIQELIAIgAzYCACABCxQBAn4gACABECAhAyAAIAEQDCADC/sBAgR/AX4gACgCyAEiBSgCECIEQTBqIQYgBCAEKAIYIAFxQX9zQQJ0aigCACEEAkADQCAERQ0BIAEgBiAEQQFrIgdBA3RqIgQoAgRHBEAgBCgCAEH///8fcSEEDAELCyAFKAIUIAdBA3RqIQUCQCADQQFGDQAgBTUCBEIghkKAgICAwABRBEAgACACEAwgACAEKAIEENEBQX8PCyAELQADQQhxDQAgACACEAwgAEGAgAEgARDnAQ8LIAAgBSACEB1BAA8LIAAgACkDwAEiCCABIAIgCAJ/IAAoAhAoAowBIgMEQEGAgAYgAygCKEEBcQ0BGgtBgIACCxDQAQuKAQEBfwJAIAJCgICAgHCDQoCAgICQf1EgA0KAgICAcINCgICAgJB/UXFFBEAgAEGl5gBBABASDAELIAAgAUESEF4iAUKAgICAcINCgICAgOAAUQ0AIAGnIgQgAz4CJCAEIAI+AiAgACABQdYAQgBBAhAVGiABDwsgACADEAwgACACEAxCgICAgOAACw0AIAAgAUHMjQEQgQMLZwEBfwJAIAFBAE4EQCAAKAIQIgIoAiwgAU0NASACKAI4IAFBAnRqKAIAIgEgASgCAEEBajYCACAAIAFBBBDmAw8LQYaJAUGo7ABB1RdBycAAEAAAC0GQzgBBqOwAQdYXQcnAABAAAAuxAgEEfwJAAkACQAJAIAJCgICAgHBUDQAgAqciAy8BBhDgAUUNACADKAIoIgRFDQAgBCgCECIDQTBqIQUgAyADKAIYQX9zQQJ0QdR5cmooAgAhAwNAIANFDQMgBSADQQFrIgNBA3RqIgYoAgRBygFHBEAgBigCAEH///8fcSEDDAELCyABQoCAgIBwVA0AIAQoAhQgA0EDdGopAwAiAkKAgICAcINCgICAgIB/UQ0BCyAAECIMAgsgACACEIgCIQMgAacoAhAiAEEwaiEEIAAgAyAAKAIYcUF/c0ECdGooAgAhAANAIABFBEBBAA8LIAQgAEEDdGoiBUEIayEAIAMgBUEEaygCAEYEQCAAQQBHDwUgACgCAEH///8fcSEADAELAAsACyAAQZ3kAEEAEBILQX8LRAEBfyAAQeQBaiECIABB4AFqIQADfyAAIAIoAgAiAkYEQEEADwsgASACQQRrKAIARgR/IAJBCGsFIAJBBGohAgwBCwsLiQECA38BfgJAIAAoAhAoAowBIgJFDQADQCABQQBMBEADQCACKQMIIgRCgICAgHBUDQMgBKciAS8BBhDgAUUNAyABKAIgIgEvABEiA0GAwABxRQRAIANBgAhxRQ0EIAAgASgCQBAWDwsgAigCACICDQAMAwsACyABQQFrIQEgAigCACICDQALC0EACykBAX8gAkIgiKdBdU8EQCACpyIDIAMoAgBBAWo2AgALIAAgASACEIUEC/QBAwF+An8BfANAAkBBfyEEAkACQAJAQQcgAkIgiKciBSAFQQdrQW5JGw4IAAAAAAICAwECCyACxCEDQQAhBAwCC0EAIQQgAkKAgICAwIGA/P8AfCICQv///////////wCDQoCAgICAgID4/wBWDQFCgICAgICAgICAfyEDIAK/IgZEAAAAAAAA4MNjDQFC////////////ACEDIAZEAAAAAAAA4ENkDQEgBplEAAAAAAAA4ENjBEAgBrAhAwwCC0KAgICAgICAgIB/IQMMAQsgACACEJYBIgJCgICAgHCDQoCAgIDgAFINAQsLIAEgAzcDACAEC+YBAgN/AXwDQAJAQX8hBAJAAkACQEEHIAJCIIinIgUgBUEHa0FuSRsOCAAAAAACAgMBAgsgAqchA0EAIQQMAgtBACEEIAJCgICAgMCBgPz/AHwiAkL///////////8Ag0KAgICAgICA+P8AVgRADAILQYCAgIB4IQMgAr8iBkQAAAAAAADgwWMNAUH/////ByEDIAZEAADA////30FkDQEgBplEAAAAAAAA4EFjBEAgBqohAwwCC0GAgICAeCEDDAELIAAgAhCWASICQoCAgIBwg0KAgICA4ABSDQELCyABIAM2AgAgBAttAAJAAkACQAJAAkAgAkEEdkEDcUEBaw4DAAECAwsgASgCACICBEAgACACrUKAgICAcIQQIQsgASgCBCIBRQ0DIAAgAa1CgICAgHCEECEPCyAAIAEoAgAQ5QEPCyABEOAFDwsgACABKQMAECELC/UBAQl/QX8hAiABIAFBAWtxRQRAIABBEGoiCCABQQJ0IgMgACgCABEDACIFBH8gBUEAIAMQLCEGIAFB/////wNqQf////8DcSEJIAAoAjQhBwNAIAQgACgCJE9FBEAgByAEQQJ0aigCACECA0AgAgRAIAAoAjggAkECdGooAgAiAygC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QQpPBH8gAEHBAGsgA00EQCAAQTdrDwsgAiAAQdcAayAAQeEAayABTxsFIAQLC6IDAQJ/IAAgASgCBBAQA0AgASgCECEDIAIgASgCFE5FBEAgACADIAJBA3RqKAIAEBAgAkEBaiECDAELCyAAKAIQIgJBEGogAyACKAIEEQAAQQAhAgNAAkAgASgCHCEDIAIgASgCIE4NACADIAJBFGxqIgMoAghFBEAgACgCECADKAIEEOUBCyAAIAMoAhAQECAAIAMoAgwQECACQQFqIQIMAQsLIAAoAhAiAkEQaiADIAIoAgQRAAAgACgCECICQRBqIAEoAiggAigCBBEAAEEAIQIDQCABKAI0IQMgAiABKAI4TkUEQCAAIAMgAkEMbGooAgQQECACQQFqIQIMAQsLIAAoAhAiAkEQaiADIAIoAgQRAAAgACgCECICQRBqIAEoAmQgAigCBBEAACAAIAEpA0AQDCAAIAEpA0gQDCAAIAEpA6gBEAwgACABKQOwARAMIAAgASkDiAEQDCAAIAEpA5ABEAwgACABKQOYARAMIAEoAggiAiABKAIMIgM2AgQgAyACNgIAIAFCADcCCCAAKAIQIgBBEGogASAAKAIEEQAAC9IDAgJ+An8jAEEgayIEJAACQCABQv///////////wCDIgNCgICAgICAwIA8fSADQoCAgICAgMD/wwB9VARAIAFCBIYgAEI8iIQhAyAAQv//////////D4MiAEKBgICAgICAgAhaBEAgA0KBgICAgICAgMAAfCECDAILIANCgICAgICAgIBAfSECIABCgICAgICAgIAIUg0BIAIgA0IBg3whAgwBCyAAUCADQoCAgICAgMD//wBUIANCgICAgICAwP//AFEbRQRAIAFCBIYgAEI8iIRC/////////wODQoCAgICAgID8/wCEIQIMAQtCgICAgICAgPj/ACECIANC////////v//DAFYNAEIAIQIgA0IwiKciBUGR9wBJDQAgBEEQaiAAIAFC////////P4NCgICAgICAwACEIgIgBUGB9wBrEGIgBCAAIAJBgfgAIAVrEI0CIAQpAwhCBIYgBCkDACIAQjyIhCECIAQpAxAgBCkDGIRCAFKtIABC//////////8Pg4QiAEKBgICAgICAgAhaBEAgAkIBfCECDAELIABCgICAgICAgIAIUg0AIAJCAYMgAnwhAgsgBEEgaiQAIAIgAUKAgICAgICAgIB/g4S/C6oPAgV/D34jAEHQAmsiBSQAIARC////////P4MhCiACQv///////z+DIQsgAiAEhUKAgICAgICAgIB/gyEMIARCMIinQf//AXEhCAJAAkAgAkIwiKdB//8BcSIJQf//AWtBgoB+TwRAIAhB//8Ba0GBgH5LDQELIAFQIAJC////////////AIMiDUKAgICAgIDA//8AVCANQoCAgICAgMD//wBRG0UEQCACQoCAgICAgCCEIQwMAgsgA1AgBEL///////////8AgyICQoCAgICAgMD//wBUIAJCgICAgICAwP//AFEbRQRAIARCgICAgICAIIQhDCADIQEMAgsgASANQoCAgICAgMD//wCFhFAEQCADIAJCgICAgICAwP//AIWEUARAQgAhAUKAgICAgIDg//8AIQwMAwsgDEKAgICAgIDA//8AhCEMQgAhAQwCCyADIAJCgICAgICAwP//AIWEUARAQgAhAQwCCyABIA2EUARAQoCAgICAgOD//wAgDCACIAOEUBshDEIAIQEMAgsgAiADhFAEQCAMQoCAgICAgMD//wCEIQxCACEBDAILIA1C////////P1gEQCAFQcACaiABIAsgASALIAtQIgYbeSAGQQZ0rXynIgZBD2sQYkEQIAZrIQYgBSkDyAIhCyAFKQPAAiEBCyACQv///////z9WDQAgBUGwAmogAyAKIAMgCiAKUCIHG3kgB0EGdK18pyIHQQ9rEGIgBiAHakEQayEGIAUpA7gCIQogBSkDsAIhAwsgBUGgAmogCkKAgICAgIDAAIQiEkIPhiADQjGIhCICQgBCgICAgLDmvIL1ACACfSIEQgAQYSAFQZACakIAIAUpA6gCfUIAIARCABBhIAVBgAJqIAUpA5gCQgGGIAUpA5ACQj+IhCIEQgAgAkIAEGEgBUHwAWogBEIAQgAgBSkDiAJ9QgAQYSAFQeABaiAFKQP4AUIBhiAFKQPwAUI/iIQiBEIAIAJCABBhIAVB0AFqIARCAEIAIAUpA+gBfUIAEGEgBUHAAWogBSkD2AFCAYYgBSkD0AFCP4iEIgRCACACQgAQYSAFQbABaiAEQgBCACAFKQPIAX1CABBhIAVBoAFqIAJCACAFKQO4AUIBhiAFKQOwAUI/iIRCAX0iAkIA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IAUgA0E5ShshAwJAIBdCB1cEQCADIAdBBHRqIQcMAQsgF0IcWARAIAJBMGogAxB4IAJBIGogHCAYQgBCgICAgICAwP0/ECsgAkEQaiACKQMwIAIpAzggAikDICIcIAIpAygiGBArIAIgAikDECACKQMYIBkgGxBvIAIpAwghGyACKQMAIRkMAQsgA0UgCHINACACQdAAaiAcIBhCAEKAgICAgICA/z8QKyACQUBrIAIpA1AgAikDWCAZIBsQbyACKQNIIRtBASEIIAIpA0AhGQsgF0IBfCEXQQEhCQsgACgCBCIDIAAoAmhHBH8gACADQQFqNgIEIAMtAAAFIAAQTwshAwwBCwsCfiAJRQRAIAApA3BCAFkEQAJAIAAgACgCBCIDQQFrNgIEIAAgA0ECazYCBCABRQ0AIAAgA0EDazYCBAsLIAJB4ABqIAS3RAAAAAAAAAAAohCpASACKQNgIRkgAikDaAwBCyAXQgdXBEAgFyEYA0AgB0EEdCEHIBhCAXwiGEIIUg0ACwsCQAJAAkAgA0FfcUHQAEYEQCAAEIEGIhhCgICAgICAgICAf1INAyAAKQNwQgBZDQEMAgtCACEYIAApA3BCAFMNAgsgACAAKAIEQQFrNgIEC0IAIRgLIAdFBEAgAkHwAGogBLdEAAAAAAAAAACiEKkBIAIpA3AhGSACKQN4DAELIBogFyABG0IChiAYfEIgfSIXQQAgD2utVQRAQcTUBEHEADYCACACQaABaiAEEHggAkGQAWogAikDoAEgAikDqAFCf0L///////+///8AECsgAkGAAWogAikDkAEgAikDmAFCf0L///////+///8AECsgAikDgAEhGSACKQOIAQwBCyAPQeIBa6wgF1cEQCAHQQBOBEADQCACQaADaiAZIBtCAEKAgICAgIDA/79/EG8gGSAbQoCAgICAgID/PxD1BSEAIAJBkANqIBkgGyACKQOgAyAZIABBAE4iABsgAikDqAMgGyAAGxBvIBdCAX0hFyACKQOYAyEbIAIpA5ADIRkgB0EBdCAAciIHQQBODQALCwJ+IBcgD6x9QiB8IhinIgBBACAAQQBKGyANIBggDa1TGyIAQfEATgRAIAJBgANqIAQQeCACKQOIAyEaIAIpA4ADIRxCAAwBCyACQeACakQAAAAAAADwP0GQASAAaxDVARCpASACQdAC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QQFqNgIEIAEtAAAMAQsgABBPC0Ewa0EKSQ0ACwsgACkDcEIAWQRAIAAgACgCBEEBazYCBAtCACAFfSAFIAMbIQUMAQtCgICAgICAgICAfyEFIAApA3BCAFMNACAAIAAoAgRBAWs2AgRCgICAgICAgICAfw8LIAULygYCBX8EfiMAQYABayIFJAACQAJAAkAgAyAEQgBCABDrAUUNAAJ/IARC////////P4MhCwJ/IARCMIinQf//AXEiBkH//wFHBEBBBCAGDQEaQQJBAyADIAuEUBsMAgsgAyALhFALCyEJIAJCMIinIghB//8BcSIHQf//AUYNACAJDQELIAVBEGogASACIAMgBBArIAUgBSkDECICIAUpAxgiASACIAEQ9AUgBSkDCCECIAUpAwAhBAwBCyABIAJC////////////AIMiCyADIARC////////////AIMiChDrAUEATARAIAEgCyADIAoQ6wEEQCABIQQMAgsgBUHwAGogASACQgBCABArIAUpA3ghAiAFKQNwIQQMAQsgBEIwiKdB//8BcSEGIAcEfiABBSAFQeAAaiABIAtCAEKAgICAgIDAu8AAECsgBSkDaCILQjCIp0H4AGshByAFKQNgCyEEIAZFBEAgBUHQAGogAyAKQgBCgICAgICAwLvAABArIAUpA1giCkIwiKdB+ABrIQYgBSkDUCEDCyAKQv///////z+DQoCAgICAgMAAhCEMIAtC////////P4NCgICAgICAwACEIQsgBiAHSARAA0ACfiALIAx9IAMgBFatfSIKQgBZBEAgCiAEIAN9IgSEUARAIAVBIGogASACQgBCABArIAUpAyghAiAFKQMgIQQMBQsgCkIBhiAEQj+IhAwBCyALQgGGIARCP4iECyELIARCAYYhBCAHQQFrIgcgBkoNAAsgBiEHCwJAIAsgDH0gAyAEVq19IgpCAFMEQCALIQoMAQsgCiAEIAN9IgSEQgBSDQAgBUEwaiABIAJCAEIAECsgBSkDOCECIAUpAzAhBAwBCyAKQv///////z9YBEADQCAEQj+IIQ0gB0EBayEHIARCAYYhBCANIApCAYaEIgpCgICAgICAwABUDQALCyAIQYCAAnEhBiAHQQBMBEAgBUFAayAEIApC////////P4MgB0H4AGogBnKtQjCGhEIAQoCAgICAgMDDPxAr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6e0AQdjsAEHUIUGzxAAQAAALCyAFQQxqEBkgBUEgaiQAQRALrwEBAn8jAEEgayIEJAAgACgCACEFIARBCGogA0EAEO0BIAAgASAEKAIIIgEgAUEfdSIBcyABayIBIAJBwAAgAUEBa2dBAXRrQQAgAUECTxtqQQhqIgJB4A8QrwMhASADKAIEBEAgBEIANwIYIARCgICAgICAgICAfzcCECAEIAU2AgwgBEEMaiIDQgEQMhogACADIAAgAkHgDxCIASABciEBIAMQGQsgBEEgaiQAIAELkAYCCH8BfiMAQfAAayIDJAAgACABRwRAIAAoAgAhBCADQgA3AmggA0KAgICAgICAgIB/NwJgIAMgBDYCXCADQdwAaiIFIAEQSRogA0IANwJUIANCgICAgICAgICAfzcCTCADIAQ2AkggAygCZCEGIANBADYCZCADQcgAaiIBQqrVqtUKEDIaIANBADYCUCAFIAEQrAIEQCADIAMoAmRBAWo2AmQgBkEBayEGCyADQcgAahAZIAJBAWpBAXYQuQQhBSADQgA3AlQgA0KAgICAgICAgIB/NwJMIAMgBDYCSCADQgA3AkAgA0KAgICAgICAgIB/NwI4IAMgBDYCNCADQdwAaiIBIAFCf0H/////A0EAEHoaIAVBACAFQQBKGyEJIAIgBWogAiAFQQF0bkEBaiIKQQF0akEgaiECQQAhAQNAIAEgCUZFBEAgA0HIAGoiByADQdwAaiIIQgEgAkEAEHoaIANBNGoiCyAHIAJBBhC1BCAHIAtCASACQQAQehogCCAIIAcgAkEAEIgBGiABQQFqIQEMAQsLIANCADcCLCADQoCAgICAgICAgH83AiQgAyAENgIgIANCADcCGCADQoCAgICAgICAgH83AhAgAyAENgIMIANBIGoiASADQdwAaiIEQgIgAkEAEHoaIAEgBCABIAJBABCIARogA0EMaiABIAEgAkEAEEAaIABCABAyGiAKrSEMA0AgDKdBAExFBEAgA0HIAGoiAUIBEDIaIANBNGoiBCAMQgGGQv7///8Pg0IBhBAyGiABIAEgBCACQQAQiAEaIAAgACABIAJBABC4ARogACAAIANBDGogAkEAEEAaIAxCAX0hDAwBCwsgACAAQgEgAkEAEHoaIAAgACADQSBqIgEgAkEAEEAaIAEQGSADQQxqEBkgA0E0ahAZ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C0KAgICAMCEFIAZCgICAgHCDQoCAgIAwUQ0DIAAgBkEBEJABGgwDC0KAgICAMCEJQoCAgIAwIQZCgICAgDAhBSAAIAQQICIHQoCAgIBwg0KAgICA4ABRDQILIAAgDUEIaiAHEC9BAEgNACANAn4gDSkDCCIEQoCAgIAIfEL/////D1gEQCAEQv////8PgwwBC0KAgICAwH4gBLm9IgVCgICAgMCBgPz/AH0gBUL///////////8Ag0KAgICAgICA+P8AVhsLIgg3AyAgACABQQEgDUEgahC/AyEFIAAgCBAMAkAgBUKAgICAcINCgICAgOAAUQ0AQgAhCCAEQgAgBEIAVRshDANAIAggDFENBCAAIAcgCBBsIgRCgICAgHCDQoCAgIDgAFENAQJAIA4EQCAEIQEMAQsgDSAENwMgIA0gCEL/////D4M3AyggACAKIAtBAiANQSBqEBwhASAAIAQQDCABQoCAgIBwg0KAgICA4ABRDQILIAAgBSAIIAEQeyERIAhCAXwhCCARQQBODQALCwwBC0KAgICAMCEFCyAAIAUQDEKAgICA4AAhBQsgACAHEAwgACAGEAwgACAJEAwgDUEwaiQAIAULDwAgACsDACABKwMAEMQECzkBAX5CgICAgMB+IAEpAwAiAkKAgICAwIGA/P8AfSACQv///////////wCDQoCAgICAgID4/wBWGwsRACAAKgIAuyABKgIAuxDEBAs7AQF+QoCAgIDAfiABKgIAu70iAkKAgICAwIGA/P8AfSACQv///////////wCDQoCAgICAgID4/wBWGwsZAQJ+IAEpAwAiAyAAKQMAIgRUIAMgBFZrCwwAIAAgASkDABCIBAsZAQJ+IAEpAwAiAyAAKQMAIgRTIAMgBFVrCwwAIAAgASkDABC/AgsXACABKAIAIgEgACgCACIASSAAIAFJaws9AQF+IAEoAgAiAEEATgRAIACtDwtCgICAgMB+IAC4vSICQoCAgIDAgYD8/wB9IAJCgICAgICAgPj/AFYbC9sFAwV/A34BfCMAQUBqIgUkAAJAAnwCQAJAAkACQAJAIAJBACABQoCAgIBwgyILQoCAgIAwUhsiAg4CAgABCwJAIAMpAwAiCUKAgICAcFQNACAJpyIELwEGQQpHDQAgBCkDICIKQiCIpyIEQQAgBEELakESSRsNACAAIAUg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IQULIAJBEGokACAFCx0AIAAgAUEAEGsiAEUEQEKAgICA4AAPCyAANQIoCz0BAX5CgICAgBAhASADKQMAIgRCgICAgHBaBH4gBKcvAQZBFWtB//8DcUEMSa1CgICAgBCEBUKAgICAEAsL7gMCBX4CfyMAQSBrIgokAEKAgICA4AAhBQJAIAAgASAEEFoiC0UNACALLQAEBEAgABBfDAELIAAgCkEYaiADKQMAQgAgCzQCACIGIAYQZg0AIAogBjcDECADKQMIIgdCgICAgHCDQoCAgIAwUgRAIAAgCkEQaiAHQgAgBiAGEGYNASAKKQMQIQYLIAopAxghCSAAIAFCgICAgDAQ/QEiB0KAgICAcIMiBUKAgICA4ABRBEAgByEFDAELIAYgCX0iBkIAIAZCAFUbIQgCQCAFQoCAgIAwUQRAIABCgICAgDAgCCAEEOUDIQUMAQsgCiAGQv////8HVwR+IAhC/////w+DBUKAgICAwH4gCLm9IgVCgICAgMCBgPz/AH0gBUL///////////8Ag0KAgICAgICA+P8AVhsLNwMIIAAgB0EBIApBCGoQowEhBSAAIAcQDCAAIAopAwgQDAsgBUKAgICAcINCgICAgOAAUQ0AAkAgACAFIAQQWiICRQ0AIAAgBSABEE0EQCAAQco0QQAQEgwBCwJAIAItAAQNACACNAIAIAhTBEAgAEHOwgBBABASDAILIAstAAQNACACKAIIIAsoAgggCadqIAinEB4aDAILIAAQXwsgACAFEAxCgICAgOAAIQULIApBIGokACAFC1EAIAAgASACEFoiAEUEQEKAgICA4AAPCyAAKAIAIgBBAE4EQCAArQ8LQoCAgIDAfiAAuL0iAUKAgICAwIGA/P8AfSABQoCAgICAgID4/wBWGwv/AwICfwF+AkACQAJAAkACQAJAIAFCgICAgHBaBEAgAaciAi8BBkErRg0BCyAEQQE2AgAMAQsgAigCICEGIARBATYCACAGDQELIABBsS1BABASDAELIAYoAgQhAgJAAkACQAJ/AkACQAJAAkAgBigCACIHQQFrDgQCAgcBAAsgBUUNAiAAIAYQyQQLQoCAgIAwIQEgBUEBaw4CAwQHCyADKQMAIgFCIIinQXVPBEAgAaciAyADKAIAQQFqNgIACwJAIAVBAkcNAEEBIQMgB0EBRw0AIAAgARCYASAGKAIEDAILIAIoAmQiAyAFrTcDACADQQhrIAE3AwAgAiADQQhqNgJkC0EAIQMgAgsiBSADNgIcIAZBAzYCACAAIAUQsQIhASAGQQE2AgAgBigCBCgCIARAIAAgBhDJBCABDwsgAUKAgICAEFoNBSACKAJkQQhrIgApAwAhCCAAQoCAgIAwNwMAIAFCAlEEQCAGQQI2AgAgBEECNgIAIAgPCyAEQQA2AgAgCA8LIAMpAwAiAUIgiKdBdUkNAyABpyIAIAAoAgBBAWo2AgAgAQ8LIAMpAwAiAUIgiKdBdU8EQCABpyICIAIoAgBBAWo2AgALIAAgARCYAQwBCyAAQY8tQQAQEgtCgICAgOAAIQELIAEPC0HW8QBBqOwAQaCUAUHEFBAAAAt3AQF+IAMpAwAiAUKAgICAcINCgICAgIB/UgRAIABBkcEAQQAQEkKAgICA4AAPC0KAgICAMCEEIAGnIgApAgRCgICAgICAgIBAg0KAgICAgICAgIB/UQR+IAAgACgCAEEBajYCACABQoCAgICQf4QFQoCAgIAwCws8AQF+QoCAgIDgACEBIAAgAykDABAlIgRCgICAgHCDQoCAgIDgAFIEfiAAIASnQQIQ5gMFQoCAgIDgAAsLVgIBfgF/IAAgARC7AyIBQoCAgIBwg0KAgICA4ABRBEAgAQ8LQoCAgIAwIQIgAaciAygCBEGAgICAeEcEQCAAIAAoAhAgAxDGAhApIQILIAAgARAMIAILCQAgACABELsDC1sBAX4jAEEQayICJAAgAiAAIAEQuwMiATcDCAJAIAFCgICAgHCDQoCAgIDgAFEEQCABIQQMAQsgAEKAgICAMEEBIAJBCGoQygQhBCAAIAEQDAsgAkEQaiQAIAQLLQBCgICAgOAAIAAgAykDACADKQMIQQAQiQIiAEEAR61CgICAgBCEIABBAEgbC6ABAQN+IAMpAwAiBSEEIAJBBE4EQCADKQMYIQQLIAVC/////29YBEAgABAiQoCAgIDgAA8LIAMpAxAhAUKAgICA4AAhBgJAIAAgAykDCBAwIgJFDQAgAUIgiKdBdU8EQCABpyIDIAMoAgBBAWo2AgALIAAgBSACIAEgBEEAENABIQMgACACEBAgA0EASA0AIANBAEetQoCAgIAQhCEGCyAGCyoAIAMpAwAiAUL/////b1gEQCAAECJCgICAgOAADwsgACABQQNBABCyAgtjAQF+IAMpAwAiBEL/////b1gEQCAAECJCgICAgOAADwtCgICAgOAAIQECQCAAIAMpAwgQMCICRQ0AIAAgBCACEG4hAyAAIAIQECADQQBIDQAgA0EAR61CgICAgBCEIQELIAELYwEDfgJAAkAgAykDACIBQv////9vWARAIAAQIgwBCyADKQMIIQUgASEEIAJBA04EQCADKQMQIQQLIAAgBRAwIgINAQtCgICAgOAADwsgACABIAIgBEEAEBEhBiAAIAIQECAGC2YBAX4gAykDACIEQv////9vWARAIAAQIkKAgICA4AAPC0KAgICA4AAhAQJAIAAgAykDCBAwIgJFDQAgACAEIAJBABDNASEDIAAgAhAQIANBAEgNACADQQBHrUKAgICAEIQhAQsgAQuaAQIBfwJ+IwBBEGsiBCQAIAMpAwghBSADKQMAIgYhAQJAAkACQAJAIAJBA0gNACADKQMQIgFCgICAgHBaBEAgAactAAVBEHENAQsgAEGdLEEAEBIMAQsgACAEQQxqIAUQ/QMiAg0BC0KAgICA4AAhAQwBCyAAIAYgASAEKAIMIgMgAhD+AiEBIAAgAiADEIYDCyAEQRBqJAAgAQt5AQF/IAFCgICAgHCDQoCAgIAwUgRAIABBnSxBABASQoCAgIDgAA8LAn4CQCACRQ0AIAMpAwAiAUKAgICAcINCgICAgDBRDQBCgICAgOAAIAAgARAlIgFCgICAgHCDQoCAgIDgAFENARogAachBAsgACAEQQMQ5gMLCxUAIAAgAykDACADIANBCGpBAhCIAws3ACMAQRBrIgIkACAAIAJBDGogAykDABB1IQAgAigCDCEDIAJBEGokAEKAgICA4AAgA2etIAAbC04AIwBBEGsiAiQAQoCAgIDgACEBAkAgACACQQxqIAMpAwAQdQ0AIAAgAkEIaiADKQMIEHUNACACKAIIIAIoAgxsrSEBCyACQRBqJAAgAQsGACAAtrsLfwAgACAAKQPQASIBQgyIIAGFIgFCGYYgAYUiAUIbiCABhSIBNwPQAUKAgICAwH4gAUKdurP7lJL9oiV+QgyIQoCAgICAgID4P4S/RAAAAAAAAPC/oL0iAUKAgICAwIGA/P8AfSABQv///////////wCDQoCAgICAgID4/wBWGwuIBAMFfAV/AX4jAEEQayIKJAAgCkIANwMIAkACQCACQQBMDQBCgICAgOAAIQEgACAKQQhqIAMpAwAQQg0BQQEhCyAKKwMIIQQgAkEBRwRAA0AgAiALRg0CIAAgCiADIAtBA3RqKQMAEEINAyALQQFqIQsgCisDACEFIwBBIGsiCSQAAkAgBJkiByAFmSIGIAe9IAa9VCIMGyIEvSIOQjSIpyINQf8PRg0AIAYgByAMGyEFAkAgDlANACAFvUI0iKciDEH/D0YNACAMIA1rQcEATgRAIAcgBqAhBAwCCwJ8IAxB/gtPBEAgBEQAAAAAAAAwFKIhBCAFRAAAAAAAADAUoiEFRAAAAAAAALBrDAELRAAAAAAAAPA/IA1BvARLDQAaIAREAAAAAAAAsGuiIQQgBUQAAAAAAACwa6IhBUQAAAAAAAAwFAshCCAJQRhqIAlBEGogBRCIBiAJQQhqIAkgBBCIBiAIIAkrAwAgCSsDEKAgCSsDCKAgCSsDGKCfoiEEDAELIAUhBAsgCUEgaiQADAALAAsgBJkhBAsgBL0iAQJ/IASZRAAAAAAAAOBBYwRAIASqDAELQYCAgIB4CyIAt71RBEAgAK0hAQwBC0KAgICAwH4gAUKAgICAwIGA/P8AfSABQv///////////wCDQoCAgICAgID4/wBWGyEBCyAKQRBqJAAgAQtOACAAIABEAAAAAAAA8L9EAAAAAAAA8D8gAEQAAAAAAAAAAGMbIAC9Qv///////////wCDQoCAgICAgID4/wBWGyAARAAAAAAAAAAAYRsLgwECAn4BfyAAvSIBQjSIp0H/D3EiA0H+B00EQCABQoCAgICAgICAgH+DIQIgA0H+B0cgAUKAgICAgICA8L9/UXJFBEAgAkKAgICAgICA+D+Evw8LIAK/DwsgA0GyCE0EfCABQj+HIAF8QgFBswggA2uthiIBQgGIfEIAIAF9g78FIAALC4IFAwJ8BX8CfiMAQRBrIgkkAAJ+QoCAgIDA/v/7/wBCgICAgMD+/3sgBBsgAkUNABoCfCADKQMAIgFC/////w9YBEBBASACIAJBAUwbIQogAachCEEBIQcDQCAHIApHBEAgCLcgAyAHQQN0aikDACIBQoCAgIAQWg0DGiAIIAGnIgsgCCALShsgCCALIAggC0gbIAQbIQggB0EBaiEHDAELCyAIrQwCC0KAgICA4AAgACAJQQhqIAEQQg0BGkEBIQcgCSsDCAshBSAHIAIgAiAHSBshAgNAIAIgB0cEQEKAgICA4AAgACAJIAMgB0EDdGopAwAQQg0CGgJAIAW9IgxC////////////AINCgICAgICAgPj/AFYNACAJKwMAIga9IgFC////////////AINCgICAgICAgPj/AFYEQCAGIQUMAQsgBUQAAAAAAAAAAGEgBkQAAAAAAAAAAGFxIQogBARAIAoEQCABIAyDvyEFDAILIAUgBSAGpSAGvUL///////////8Ag0KAgICAgICA+P8AVhsgBiAFvUL///////////8Ag0KAgICAgICA+P8AWBshBQwBCyAKBEAgASAMhL8hBQwBCyAFIAUgBqQgBr1C////////////AINCgICAgICAgPj/AFYbIAYgBb1C////////////AINCgICAgICAgPj/AFgbIQULIAdBAWohBwwBCwsgBb0iAQJ/IAWZRAAAAAAAAOBBYwRAIAWqDAELQYCAgIB4CyIAt71RBEAgAK0MAQtCgICAgMB+IAFCgICAgMCBgPz/AH0gAUL///////////8Ag0KAgICAgICA+P8AVhsLIQ0gCUEQaiQAIA0L4wECAX4CfyMAQRBrIgIkAAJAIAAgAUEpEFoiA0UEQCAEQQA2AgBCgICAgOAAIQEMAQtCgICAgDAhAQJAIAMpAwAiBkKAgICAcINCgICAgDBSBEAgAiADKAIMIgU2AgwgBSAGpyIHKAIEQf////8HcUkNASAAIAYQDCADQoCAgIAwNwMACyAEQQE2AgAMAQsgByACQQxqEMYBIQggAyACKAIMNgIMIARBADYCACAIQf//A00EQCAAIAhB//8DcRCUAyEBDAELIAAgByAFQQF0akEQakECEJIDIQELIAJBEGokACABC5EDAgN/An4jAEEgayICJABCgICAgOAAIQgCQCAAIAEQSiIBQoCAgIBwg0KAgICA4ABRDQAgACACQQhqIgVBBxA+GiAFQTwQPBogBSAEQQN0IgRB0OEBaigCACIGEIMBGiAEQdThAWooAgAiBARAIAVBIBA8GiAFIAQQgwEaIAVB2pEBEIMBGiAAIAMpAwAQSiIJQoCAgIBwg0KAgICA4ABRBEAgACABEAwgAigCCCgCECIAQRBqIAIoAgwgACgCBBEAAAwCCyAJpyIH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QdAAaiQAIAYLuAICA38DfiMAQSBrIgIkAEKAgICA4AAhBwJAAkACQCAAIAEQSiIBQoCAgIBwg0KAgICA4ABRDQAgACACIAMpAwAQ4wENACACKQMAIghCgICAgAhaBEAgAEHTGEEAEEQMAQsgCKciA0EBRg0BIAGnIgQpAgQiCaciBkH/////B3EiBUUNASAJQv////8HgyAIfkKAgICABFoEQCAAQeTIAEEAEDoMAQsgACACQQhqIAMgBWwgBkEfdhCZAw0AAkAgBUEBRwRAA0AgA0EATA0CIAJBCGogBEEAIAUQSxogA0EBayEDDAALAAsgAkEIagJ/IAQtAAdBgAFxBEAgBC8BEAwBCyAELQAQCyADEMsEGgsgACABEAwgAkEIahA3IQcMAgsgACABEAwMAQsgASEHCyACQSBqJAAgBwtYAQF+IAAgAykDABDkAUEAR61CgICAgBCEIQQgAUKAgICAcINCgICAgDBRBEAgBA8LIAAgAUEGEF4iAUKAgICAcINCgICAgOAAUgRAIAAgASAEEL0BCyABC8EBAgJ/An4jAEEQayIEJABCgICAgOAAIQYCQCAAIAEQSiIBQoCAgIBwg0KAgICA4ABRBEAgASEGDAELAkAgACAEQQxqIAMpAwAgAaciBSgCBEH/////B3EiAiACEFYNACAEIAI2AgggAykDCCIHQoCAgIBwg0KAgICAMFIEQCAAIARBCGogByACIAIQVg0BIAQoAgghAgsgACAFIAQoAgwiAyACIAMgAiADShsQjgEhBgsgACABEAwLIARBEGokACAGC8ABAgN/An4jAEEQayICJABCgICAgOAAIQcCQCAAIAEQSiIBQoCAgIBwg0KAgICA4ABRBEAgASEHDAELAkAgACACQQxqIAMpAwAgAaciBigCBEH/////B3EiBCAEEFYNACACIAQgAigCDCIFayIENgIIIAAgBiAFIAMpAwgiCEKAgICAcINCgICAgDBSBH8gACACQQhqIAggBEEAEFYNASACKAIIBSAECyAFahCOASEHCyAAIAEQDAsgAkEQaiQAIAcL0wECAn8CfiMAQRBrIgIkAEKAgICA4AAhBgJAIAAgARBKIgFCgICAgHCDQoCAgIDgAFEEQCABIQYMAQsCQCAAIAJBDGogAykDACABpyIFKAIEQf////8HcUEAEFYNACACIAUo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ABogAy0AAEEBcUUEQCADKAI4IQAgAygCNCIBBEAgASAANgI4CyAABEAgACABNgI0CyADQZjVBCgCAEYEQEGY1QQgADYCAAsgAygCYBDUASADENQBCyAMEAogDBDUAQsgB0HQAWokAAsJACAAIAEQzwQLLAAgACABEM8EIgFCgICAgHCDQoCAgIDgAFIEfiAAQQNBAiABpxsQKQUgAQsLkAECAXwBfiMAQRBrIgIkAAJ+IAMpAwAiAUIgiKciAwRAQoCAgIAQIANBC2pBEkkNARoLQoCAgIDgACAAIAJBCGogARBCDQAaIAIrAwgiBJlE////////P0NlIAS9QoCAgICAgID4/wCDQoCAgICAgID4/wBSIAScIARhcXGtQoCAgIAQhAshBSACQRBqJAAgBQsmAEKAgICA4AAgACADKQMAENkFIgBBAEetQoCAgIAQhCAAQQBIGwsvAQF+An4gAygCBCICBEBCgICAgBAiBCACQQtqQRJJDQEaCyAAIAQgAyADENIECwsvAQF+An4gAygCBCICBEBCgICAgBAiBCACQQtqQRJJDQEaCyAAIAQgAyADENMECwsJACAAIAEQngILowECAn4BfyMAQRBrIgIkAAJ+IAAgARCeAiIFQoCAgIBwg0KAgICA4ABRBEAgBQwBC0EKIQcCQAJAIAQNACADKQMAIgFCgICAgHCDQoCAgIAwUQ0AIAAgARDbBCIHQQBIDQELQoCAgIDgACAAIAJBCGogBRBtDQEaIAAgAisDCCAHQQBBABC6AgwBCyAAIAUQDEKAgICA4AALIQYgAkEQaiQAIAYLkAICAX4BfCMAQRBrIgIkAEKAgICA4AAhBAJAIAAgARCeAiIBQoCAgIBwg0KAgICA4ABRBEAgASEEDAELIAAgAiABEG0NAAJAAkAgAykDACIBQoCAgIBwg0KAgICAMFEEQCACKwMAIgW9IQEMAQsgACACQQxqIAEQswENAiACKwMAIgW9IgFCgICAgICAgPj/AINCgICAgICAgPj/AFINAQsgAEKAgICAwH4gAUKAgICAwIGA/P8AfSAFvUL///////////8Ag0KAgICAgICA+P8AVhsQNCEEDAELIAIoAgwiA0HlAGtBm39NBEAgAEHrIUEAEEQMAQsgACAFQQogA0EBELoCIQQLIAJBEGokACAEC80BAgF+AnwjAEEQ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IAQgCjcDACAEQQhqIQQgCEIBfCEIDAELCyAJIAx8IQgDQCAIIAtZDQIgBiAIp0EDdGopAwAiCUIgiKdBdU8EQCAJpyIDIAMoAgBBAWo2AgALIAQgCTcDACAEQQhqIQQgCEIBfCEIDAALAAsDQAJAIAkgClEEQCADQRBqIQNCACEJA0AgCSAPUQ0CIAMgCadBA3RqKQMAIhBCIIinQXVPBEAgEKciBiAGKAIAQQFqNgIACyAEIBA3AwAgBEEIaiEEIAlCAXwhCQwACwALIAAgDiAJIAQQVEF/Rg0DIARBCGohBCAJQgF8IQkMAQsLIAogDHwhCQNAIAkgC1kNASAAIA4gCSAEEFRBf0YNAiAEQQhqIQQgCUIBfCEJDAALAAsgAiAERgRAIAFCgICAgDAgACABQTAgDUKAgICACFoEfkKAgICAwH4gDbm9IghCgICAgMCBgPz/AH0gCEL///////////8Ag0KAgICAgICA+P8AVhsFIA0LEDlBAEgiAxshC0KAgICA4AAgASADGyEIIAIhBAwDC0GJFkGo7ABB4rkCQfHqABAAAAsgASELDAELQQAhAkKAgICAMCELCwNAIAIgBEZFBEAgBEKAgICAMDcDACAEQQhqIQQMAQsLIAAgCxAMIAAgDhAMIAVBMGokACAIC8gIAgl+A38jAEEwayIOJABCgICAgDAhBQJAAkAgACAOQSBqIAAgARAgIgoQLw0AIAAgDkEYaiADKQMAQgAgDikDICIGIAYQZg0AAkAgBARAAkACQAJAIAIOAgIAAQsgBiAOKQMYfSEHQQAhAgwBCyAAIA5BEGogAykDCEIAIAYgDikDGH1CABBmDQMgAkECayECIA4pAxAhBwsgBiACrXwgB31CgICAgICAgBBTDQEgAEH0yABBABASDAILIA4gBjcDECAGIQEgAykDCCINQoCAgIBwg0KAgICAMFIEfiAAIA5BEGogDUIAIAEgARBmDQIgDikDEAUgAQsgDikDGH0iAUIAIAFCAFUbIQdBACECCyAAIAogB0KAgICACHxC/////w9YBH4gB0L/////D4MFQoCAgIDAfiAHub0iAUKAgICAwIGA/P8AfSABQv///////////wCDQoCAgICAgID4/wBWGwsiBRCfAiEBIAAgBRAMAkAgAUKAgICAcINCgICAgOAAUQ0AIA4pAxgiDSAHfCELAkACQCAKIA5BDGogDkEIahCPAUUgAUKAgICAcFRyDQAgAaciDy8BBkECRw0AIA0hBSAPLQAFQQhxRQ0BIAUgCyAONQIIIgggCCALVRsiCCAFIAhVGyAFfSEJIA4oAgwhEANAIAkgDFENAiAQIAWnQQN0aikDACIIQiCIp0F1TwRAIAinIg8gDygCAEEBajYCAAsgACABIAwgCEGAgAEQyAFBAEgNAyAMQgF8IQwgBUIBfCEFDAALAAsgDSEFCyAFIAsgBSALVRshCANAIAUgCFIEQCAAIAogBSAOQShqEFQiD0EASA0CIA8EQCAAIAEgCSAOKQMoQYCAARDIAUEASA0DCyAJQgF8IQkgBUIBfCEFDAELCyAAIAFBMCAJQoCAgIAIWgR+QoCAgIDAfiAJub0iBUKAgICAwIGA/P8AfSAFQv///////////wCDQoCAgICAgID4/wBWGwUgCQsQOUEASA0AIAQEQCAGIAKtIgt8IAd9IQwCQCAHIAtRDQAgACAKIAsgDXwgByANfCIFIAYgBX1Bf0EBIAcgC1MbEPMCQQBIDQIDQCAGIAxXDQEgACAKIAZCAX0iBhCFAkEATg0ACwwCCyADQRBqIQNCACEFA0AgBSALUgRAIAMgBadBA3RqKQMAIghCIIinQXVPBEAgCKciAiACKAIAQQFqNgIACyAFIA18IQYgBUIBfCEFIAAgCiAGIAgQe0EATg0BDAMLCyAMQoCAgIAIfEL/////D1gEfiAMQv////8PgwVCgICAgMB+IAy5vSIFQoCAgIDAgYD8/wB9IAVC////////////AINCgICAgICAgPj/AFYbCyEJIAEhBSAAIApBMCAJEDlBAEgNAgsgCiEFDAILIAEhBQsgACAKEAxCgICAgOAAIQELIAAgBRAMIA5BMGokACABC5MEAgN/Bn4jAEEgayICJABCgICAgDAhCgJAAkAgAykDACIIQoCAgIBwg0KAgICAMFENACAAIAgQNQ0AIABB+zlBABASQoCAgIDgACEJDAELQoCAgIDgACEJAkAgACACQRBqIAAgARAgIgsQLw0AIAAgAikDECIHEOICIghCgICAgHCDQoCAgIDgAFEEQEKAgICA4AAhCgwBCwJAIAdCAFUEQCAIpygCJCEEQgAhAQJAAkAgCyACQRxqIAJBDGoQjwFFDQAgByACNQIMUg0AIAIoAhwhBQNAIAEgB1ENAiAFIAGnQQN0aikDACIMQiCIp0F1TwRAIAynIgYgBigCAEEBajYCAAsgBCAMNwMAIARBCGohBCABQgF8IQEMAAsACwNAIAEgB1ENASAAIAsgASAEEFRBf0cEQCAEQQhqIQQgAUIBfCEBDAELCyAHIAEgASAHUxshCgNAIAEgClENAyAEQoCAgIAwNwMAIARBCGohBCABQgF8IQEMAAsACyAAIAhBMCAHQoCAgIAIWgR+QoCAgIDAfiAHub0iAUKAgICAwIGA/P8AfSABQv///////////wCDQoCAgICAgID4/wBWGwUgBwsQOUEASA0BCyAAIAggBCADENUEIglCgICAgHCDQoCAgIDgAFENACAAIAkQDCAIIQkMAQsgCCEKCyAAIAoQDCAAIAsQDAsgAkEgaiQAIAkL5AIDAn4FfwF8IwBBIGsiBSQAAkAgAigCBA0AIAIoAgAhBgJAAkACfyACKAIIBEAgACkAACABKQAAUQ0CIAUgACkDADcDECAFIAEpAwA3AxggBiACKQMQQoCAgIAwQQIgBUEQahAcIgNCgICAgHCDQoCAgIDgAFENAyADQv////8PWARAIAOnIgJBH3UgAkEAR3IMAgsgBiAFQQhqIAMQbUEASA0DIAUrAwgiCkQAAAAAAAAAAGQgCkQAAAAAAAAAAGNrDAELIAAoAggiCEUEQCAGIAApAwAQJSIDQoCAgIBwg0KAgICA4ABRDQMgACADpyIINgIICyABKAIIIgkEfyAIBSAGIAEpAwAQJSIDQoCAgIBwg0KAgICA4ABRDQMgASADpyIJNgIIIAAoAggLIAkQvAILIgcNAgsgACkDECIDIAEpAxAiBFUgAyAEU2shBwwBCyACQQE2AgQLIAVBIGokACAHC9MFAgd+A38jAEEQayINJAAgAUKAgICAcINCgICAgDBRBEAgACgCECgCjAEpAwghAQsCQCAAIAFBPCABQQAQESIGQoCAgIBwg0KAgICA4ABRDQACQCAGQv////9vVg0AIAAgBhAMIAAgARD8AiIMRQRAQoCAgIDgACEGDAILAn8gBEEASARAIAwoAihBGGoMAQsgDCAEQQN0akHYAGoLKQMAIgZCIIinQXVJDQAgBqciDCAMKAIAQQFqNgIACyAAIAZBAxBHIQEgACAGEAxCgICAgOAAIQYgAUKAgICAcINCgICAgOAAUQ0AAkAgAyAEQQdGIgxBA3RqKQMAIgVCgICAgHCDQoCAgIAwUgRAIAAgBRAlIgVCgICAgHCDQoCAgIDgAFENASAAIAFBMyAFQQMQFRoLAkAgAkECQQEgDBsiAkwNACADIAJBA3RqKQMAIgVCgICAgHBUDQAgACAFQTQQbiICQQBIDQEgAkUNACAAIAVBNCAFQQAQESIFQoCAgIBwg0KAgICA4ABRDQEgACABQTQgBUEDEBUaCyAEQQdGBEBCgICAgOAAIQhCgICAgDAhBQJAAkAgACADKQMAQQAQywEiB0KAgICAcINCgICAgOAAUQRAQoCAgIAwIQkMAQsgACAHQesAIAdBABARIglCgICAgHCDQoCAgIDgAFENACAAEDsiBUKAgICAcINCgICAgOAAUQRAQoCAgIDgACEFDAELA0AgACAHIAkgDUEMahCRASILQoCAgIBwg0KAgICA4ABSBEAgDSgCDARAIAUhCAwECyAAIAUgCiALEGchDiAKQgF8IQogDkEATg0BCwsgACAHQQEQkAEaCyAAIAUQDAsgACAJEAwgACAHEAwgCEKAgICAcINCgICAgOAAUQ0BIAAgAUE1IAhBAxAVGgsgACABQQBBAEEBELQCIAEhBgwBCyAAIAEQDAsgDUEQaiQAIAYLrQMCBn4CfyMAQSBrIgMkAEKAgICAMCEGQoCAgIDgACEHAkAgACADQRBqIAAgARAgIggQLw0AIAAgAykDECIEEOICIgVCgICAgHCDQoCAgIDgAFEEQEKAgICA4AAhBgwBCwJAIARCAFUEQCAEQgF9IQEgBacoAiQhAgJAAkAgCCADQRxqIANBDGoQjwFFDQAgBCADNQIMUg0AIAMoAhwhCgNAIAFCAFMNAiAKIAGnQQN0aikDACIJQiCIp0F1TwRAIAmnIgsgCygCAEEBajYCAAsgAiAJNwMAIAJBCGohAiABQgF9IQEMAAsACwNAIAFCAFMNASAAIAggASACEFRBf0cEQCACQQhqIQIgAUIBfSEBDAELCwNAIAFCAFMNAyACQoCAgIAwNwMAIAJBCGohAiABQgF9IQEMAAsACyAAIAVBMCAEQoCAgIAIWgR+QoCAgIDAfiAEub0iAUKAgICAwIGA/P8AfSABQv///////////wCDQoCAgICAgID4/wBWGwUgBAsQOUEASA0BCyAFIQcMAQsgBSEGCyAAIAYQDCAAIAgQDCADQSBqJAAgBwumAwICfgJ/IwBBMGsiAiQAIAJCgICAgDA3AygCQAJ+QoCAgIAwIAAgAkEQaiAAIAEQICIBEC8NABogASACQRxqIAJBDGoQjwEhAyACKQMQIQUCQCADRQ0AIAUgAigCDCIDrVINACADQQJJDQJBACEAIAIoAhwhBgNAIAAgA0EBayIDTw0DIAYgAEEDdGoiBykDACEEIAcgBiADQQN0aiIHKQMANwMAIAcgBDcDACAAQQFqIQAMAAsACwNAIAQgBUIBfSIFWQ0CAkACQAJAIAAgASAEIAJBKGoQVCIDQQBIDQAgACABIAUgAkEgahBUIgZBAEgNAAJAAkAgBgRAIAAgASAEIAIpAyAQe0EASA0DIANFDQIgACABIAUgAikDKBB7QQBODQEMBQsgA0UNAyAAIAEgBBCFAkEASA0CIAAgASAFIAIpAygQe0EASA0ECyACQoCAgIAwNwMoDAILIAAgASAFEIUCQQBODQELIAIpAygMAwsgBEIBfCEEDAELC0KAgICAMAshBCAAIAQQDCAAIAEQDEKAgICA4AAhAQsgAkEwaiQAIAELhQEBAX5CgICAgOAAIQQgACABECAiAUKAgICAcINCgICAgOAAUgRAAn5CgICAgOAAIAAgAUHcACABQQAQESIEQoCAgIBwg0KAgICA4ABRDQAaIAAgBBA1RQRAIAAgBBAMIAAgASAAIAAQ1wQMAQsgACAEIAFBAEEAEDYLIQQgACABEAwLIAQLogMCAn8GfiMAQSBrIgUkAAJ+AkAgACAFIAAgARAgIgkQLw0AQSwhBgJAIAJBAEwgBHJFBEBCgICAgDAhB0EAIQIgAykDACIBQoCAgIBwg0KAgICAMFENASAAIAEQJSIHQoCAgIBwg0KAgICA4ABRDQJBfyEGIAenIgIoAgRBAUcNASACLQAQIQYMAQtCgICAgDAhB0EAIQILIAAgBUEIakEAED4aQgAhASAFKQMAIghCACAIQgBVGyELAkADQCABIAtSBEACQCABUA0AIAZBAE4EQCAFQQhqIAYQPBoMAQsgBUEIaiACQQAgAigCBEH/////B3EQSxoLIAAgCSABpxCmASIIQoCAgIBwgyIKQoCAgIAgUSAKQoCAgIAwUXJFBEAgCkKAgICA4ABRDQMgBUEIaiAEBH4gACAIENYEBSAICxCEAQ0DCyABQgF8IQEMAQsLIAAgBxAMIAAgCRAMIAVBCGoQNwwCCyAFKAIIKAIQIgJBEGogBSgCDCACKAIEEQAAIAAgBxAMCyAAIAkQDEKAgICA4AALIQwgBUEgaiQAIAwLvQICAX8DfiMAQSBrIgQkAAJ+AkACQAJAIAAgBEEQaiAAIAEQICIGEC8NACAEKQMQIgVCAFcNASAEIAVCAX0iATcDCCACQQJOBEAgACAEQQhqIAMpAwhCfyABIAUQZg0BIAQpAwghAQsDQCABQgBTDQIgACAGIAEgBEEYahBUIgJBAEgNASACBEAgAykDACIFQiCIp0F1TwRAIAWnIgIgAigCAEEBajYCAAsgACAFIAQpAxhBABC0AQ0ECyABQgF9IQEMAAsACyAAIAYQDEKAgICA4AAMAgtCfyEBCyAAIAYQDCABQv////8PgyABQoCAgIAIfEL/////D1gNABpCgICAgMB+IAG5vSIBQoCAgIDAgYD8/wB9IAFC////////////AINCgICAgICAgPj/AFYbCyEHIARBIGokACAHC+cDAgJ/B34jAEEgayIEJAACfgJAIAAgBEEQaiAAIAEQICIIEC8NAEJ/IQkCQCAEKQMQIgdCAFcNAEIAIQEgBEIANwMIIAJBAk4EQCAAIARBCGogAykDCEIAIAcgBxBmDQIgBCkDCCEBCwJAAkAgCCAEQQRqIAQQjwFFDQAgASAENQIAIgYgASAGVRshBiAEKAIEIQIDQCABIAZRBEAgBiEBDAILIAMpAwAiCkIgiKdBdU8EQCAKpyIFIAUoAgBBAWo2AgALIAIgAadBA3RqKQMAIgtCIIinQXVPBEAgC6ciBSAFKAIAQQFqNgIACyAAIAogC0EAELQBDQIgAUIBfCEBDAALAAsgASAHIAEgB1UbIQcDQCABIAdRDQIgACAIIAEgBEEYahBUIgJBAEgNAyACBEAgAykDACIGQiCIp0F1TwRAIAanIgIgAigCAEEBajYCAAsgACAGIAQpAxhBABC0AQ0CCyABQgF8IQEMAAsACyABIQkLIAAgCBAMIAlC/////w+DIAlCgICAgAh8Qv////8PWA0BGkKAgICAwH4gCbm9IgFCgICAgMCBgPz/AH0gAUL///////////8Ag0KAgICAgICA+P8AVhsMAQsgACAIEAxCgICAgOAACyEMIARBIGokACAMC+cDAgl+AX8jAEEwayIOJABCgICAgDAhBgJAAkAgACAOQQhqIAAgARAgIggQLwRAQoCAgIAwIQUMAQtCgICAgDAhBSAAIAMpAwAiChBVDQBCgICAgDAhCSACQQJOBEAgAykDCCEJCyAOKQMIIgVCAX1CACAEQX5xQQJGIgIbIQdCf0IBIAIbIQtCfyAFIAIbIQwDQCAHIAxSBEAgB0KAgICACHxC/////w9YBH4gB0L/////D4MFQoCAgIDAfiAHub0iBUKAgICAwIGA/P8AfSAFQv///////////wCDQoCAgICAgID4/wBWGwsiBUKAgICAcINCgICAgOAAUQ0CIAAgCCAFEE4iBkKAgICAcINCgICAgOAAUQ0CIA4gATcDICAOIAU3AxggDiAGNwMQIAAgCiAJQQMgDkEQahAcIg1CgICAgHCDQoCAgIDgAFENAiAAIA0QJwRAAkACQCAEQQFrDgMAAQABCyAAIAYQDCAAIAgQDAwFCyAAIAUQDCAAIAgQDCAGIQUMBAUgACAGEAwgACAFEAwgByALfCEHDAILAAsLIAAgCBAMQoCAgIAwQv////8PIARBAWtBfXEbIQUMAQsgACAFEAwgACAGEAwgACAIEAxCgICAgOAAIQULIA5BMGokACAFC6ICAgN+An8jAEEgayIHJAACQAJAIAAgB0EYaiAAIAEQICIFEC8NACAHQgA3AxACQCACQQFMBEAgBykDGCEEDAELIAcpAxghBCADKQMIIgFCgICAgHCDQoCAgIAwUgRAIAAgB0EQaiABQgAgBCAEEGYNAgsgByAENwMIIAJBAkYNACADKQMQIgFCgICAgHCDQoCAgIAwUQ0AIAAgB0EIaiABQgAgBCAEEGYNASAHKQMIIQQLIAcpAxAiASAEIAEgBFUbIQYDQCABIAZRDQIgAykDACIEQiCIp0F1TwRAIASnIgIgAigCAEEBajYCAAsgACAFIAEgBBB7IQggAUIBfCEBIAhBAE4NAAsLIAAgBRAMQoCAgIDgACEFCyAHQSBqJAAgBQvvBQIDfwl+IwBBQGoiBSQAQoCAgIAwIQsgBUKAgICAMDcDOCAFQoCAgIAwNwMwAkACQAJAIARBCHEiBwRAIAFCIIinQXVPBEAgAaciBiAGKAIAQQFqNgIACyAFIAAgARCKASIGrDcDCCAGQQBODQEMAgsgACAFQQhqIAAgARAgIgEQLw0BCyAAIAMpAwAiDxBVDQACQCACQQFMBEAgBSkDCCIMQgAgDEIAVRshCiAEQQFxIQQDQCAIIApRBEAgAEGODUEAEBIMBAsgDCAIQn+FfCAIIAQbIQkgCEIBfCEIIAcEQCAFIAAgASAJEGwiCTcDMCAJQoCAgIBwg0KAgICA4ABRDQQMAwsgACABIAkgBUEwahBUIgJBAEgNAyACRQ0ACyAFKQMwIQkMAQsgAykDCCIJQiCIp0F1TwRAIAmnIgIgAigCAEEBajYCAAsgBEEBcSEEIAUpAwghDAsgCCAMIAggDFUbIRADQCAIIBBRDQIgDCAIQn+FfCAIIAQbIQoCQAJAAkAgBwRAIAUgACABIAoQbCILNwM4IAtCgICAgHCDQoCAgIDgAFINAQwDCyAAIAEgCiAFQThqEFQiAkEASARAIAUpAzghCwwDCyACRQ0BCyAKQoCAgIAIfEL/////D1gEfiAKQv////8PgwVCgICAgMB+IAq5vSILQoCAgIDAgYD8/wB9IAtC////////////AINCgICAgICAgPj/AFYbCyENIAUpAzghCiANQoCAgIBwg0KAgICA4ABRBEAgCiELDAILIAUgATcDKCAFIA03AyAgBSAKNwMYIAUgCTcDEEKAgICAMCELIAAgD0KAgICAMEEEIAVBEGoQHCEOIAAgDRAMIAAgChAMIAVCgICAgDA3AzggDkKAgICAcINCgICAgOAAUQ0BIAAgCRAMIA4hCQsgCEIBfCEIDAELCyAFIAk3AzALIAAgBSkDMBAMIAAgCxAMQoCAgIDgACEJCyAAIAEQDCAFQUBrJAAgCQvlCAIDfwp+IwBBMGsiBSQAQoCAgIAwIQggBUKAgICAMDcDKAJAAkACQCAEQQhxIgcEQCABQiCIp0F1TwRAIAGnIgYgBigCAEEBajYCAAsgBSAAIAEQigEiBqw3AwggBkEATg0BQoCAgIDgACEJDAILQoCAgIDgACEJIAAgBUEIaiAAIAEQICIBEC8NAQsgAykDACEQQoCAgIAwIQ8gAkECTgRAIAMpAwghDwtCgICAgOAAIQkgACAQEFUNAAJAAkACQAJAAkACQAJAIAQODQUABgECBgYGBQAGAwQGC0KAgICAECEIDAULIAAgAQJ+IAUpAwgiCEKAgICACHxC/////w9YBEAgCEL/////D4MMAQtCgICAgMB+IAi5vSIIQoCAgIDAgYD8/wB9IAhC////////////AINCgICAgICAgPj/AFYbCxCfAiIIQoCAgIBwg0KAgICA4ABSDQQMBQsgACABQgAQnwIiCEKAgICAcINCgICAgOAAUg0DDAQLIAUgATcDECAFIAU1Agg3AxggAEECIAVBEGoQ4QIiCEKAgICAcINCgICAgOAAUg0CDAMLIAAQOyIIQoCAgIBwg0KAgICA4ABSDQFCgICAgOAAIQgMAgtCgYCAgBAhCAsgBSkDCCIJQgAgCUIAVRshEQNAIAogEVIEQAJAAkAgBwRAIAUgACABIAoQbCILNwMoQoCAgIDgACEJIAtCgICAgHCDQoCAgIDgAFINAQwFCyAAIAEgCiAFQShqEFQiAkEASARAQoCAgIDgACEJDAULIAJFDQELIAohCyAKQoCAgIAIWgRAQoCAgIDAfiAKub0iCUKAgICAwIGA/P8AfSAJQv///////////wCDQoCAgICAgID4/wBWGyELC0KAgICA4AAhCSALQoCAgIBwg0KAgICA4ABRDQMgBSABNwMgIAUgCzcDGCAFIAUpAygiDjcDECAAIBAgD0EDIAVBEGoQHCEMIAAgCxAMIAxCgICAgHCDQoCAgIDgAFENAwJAAkACQAJAAkACQAJAIAQODQABBQIEBQUFAAEFAwQFCyAAIAwQJw0FQoCAgIAQIQkMCgsgACAMECdFDQRCgYCAgBAhCQwJCyAAIAggCiAMEGdBAE4NAwwHCyAAIAggCkL/////D4MgDEGAgAEQzwFBAE4NAgwGCyAAIAwQJ0UNASAOQiCIp0F1TwRAIA6nIgIgAigCAEEBajYCAAsgACAIIA0gDhBnQQBIDQUgDUIBfCENDAELIAAgDBAMCyAAIA4QDCAFQoCAgIAwNwMoCyAKQgF8IQoMAQsLIARBDEcEQCAIIQkMAgsgBSABNwMQIAUgDUL/////D4M3AxhCgICAgOAAIQkgAEECIAVBEGoiAhDhAiIKQoCAgIBwg0KAgICA4ABRDQAgBSAINwMQQoCAgIDgACAKIAAgACAKQcMAQQEgAhCzAhD/ARshCQsgACAIEAwLIAAgBSkDKBAMIAAgARAMIAVBMGokACAJC60EAgV+A38jAEEQayIJJABCgICAgDAhBgJAAkAgACABECAiCEKAgICAcINCgICAgOAAUQ0AIAAgCEIAEJ8CIgZCgICAgHCDQoCAgIDgAFENAEF/IQpBfyACIAJBAEgbIQsCQANAIAogC0cEQCAIIQUgCkEATgRAIAMgCkEDdGopAwAhBQsCQAJAIAVCgICAgHBUDQACfyAAIAVB0wEgBUEAEBEiAUKAgICAcIMiB0KAgICAMFIEQCAHQoCAgIDgAFENByAAIAEQJwwBCyAAIAUQzAELIgJBAEgNBSACRQ0AIAAgCSAFEC8NBSAJKQMAIgcgBHxC/////////w9VDQRCACEBIAdCACAHQgBVGyEHA0AgASAHUQ0CIAAgBSABIAlBCGoQVCICQQBIDQYgAgRAIAAgBiAEIAkpAwgQZ0EASA0HCyAEQgF8IQQgAUIBfCEBDAALAAsgBEL+////////D1UNAyAFQiCIp0F1TwRAIAWnIgIgAigCAEEBajYCAAsgACAGIAQgBRBnQQBIDQQgBEIBfCEECyAKQQFqIQoMAQsLIAAgBkEwIARCgICAgAh8Qv////8PWAR+IARC/////w+DBUKAgICAwH4gBLm9IgFCgICAgMCBgPz/AH0gAUL///////////8Ag0KAgICAgICA+P8AVhsLEDlBAEgNAQwCCyAAQfTIAEEAEBILIAAgBhAMQoCAgIDgACEGCyAAIAgQDCAJQRBqJAAgBgvaBQIFfgN/IwBBIGsiCSQAQoCAgIAwIQRCgICAgOAAIQYCQCAAIAlBEGogACABECAiCBAvDQAgACAJQQhqIAMpAwAQ4wENACAJKQMQIQUCQAJAIAkpAwgiAUIAUwRAIAEgBXwiAUIAUw0BCyABIAVTDQELIABB3eEAQQAQRAwBCyAAIAUQ4gIiB0KAgICAcINCgICAgOAAUQRAQoCAgIDgACEEDAELIAenKAIkIQJCACEEAkACQCAIIAlBHGogCUEEahCPAUUNACAFIAk1AgRSDQBCACEGIAkoAhwhCgNAIAEgBlIEQCAKIAanQQN0aikDACIEQiCIp0F1TwRAIASnIgsgCygCAEEBajYCAAsgAiAENwMAIAJBCGohAiAGQgF8IQYMAQsLIAMpAwgiBEIgiKdBdU8EQCAEpyIDIAMoAgBBAWo2AgALIAIgBDcDAANAIAFCAXwiASAFWQ0CIAogAadBA3RqKQMAIgRCIIinQXVPBEAgBKciAyADKAIAQQFqNgIACyACQQhqIgIgBDcDAAwACwALAkACQANAIAEgBFENASAAIAggBCACEFRBf0cEQCACQQhqIQIgBEIBfCEEDAELCyAEIQEMAQsgAykDCCIEQiCIp0F1TwRAIASnIgMgAygCAEEBajYCAAsgAiAENwMAA0AgAUIBfCIBIAVZDQIgACAIIAEgAkEIaiICEFRBf0cNAAsLA0AgASAFWQRAIAchBAwDBSACQoCAgIAwNwMAIAJBCGohAiABQgF8IQEgCSkDECEFDAELAAsACyAHQoCAgIAwIAAgB0EwIAVCgICAgAh8Qv////8PWAR+IAVC/////w+DBUKAgICAwH4gBbm9IgFCgICAgMCBgPz/AH0gAUL///////////8Ag0KAgICAgICA+P8AVhsLEDlBAEgiAhshBEKAgICA4AAgByACGyEGCyAAIAQQDCAAIAgQDCAJQSBqJAAgBgvrAQEDfiMAQSBrIgIkAEKAgICA4AAhBAJAIAAgAkEQaiAAIAEQICIFEC8NACAAIAJBCGogAykDABDjAQ0AQoCAgIAwIQQgAikDCCIBIAIpAxAiBiABQj+Hg3wiAUIAUyABIAZZcg0AAkAgBSACQQRqIAIQjwFFDQAgASACNQIAWg0AIAIoAgQgAadBA3RqKQMAIgRCIIinQXVJDQEgBKciAyADKAIAQQFqNgIADAELQoCAgIDgACEEIAAgBSABIAJBGGoQVCIDQQBIDQAgAikDGEKAgICAMCADGyEECyAAIAUQDCACQSBqJAAgBAstAQF+QoCAgIAwIQICQCABEJYDIgBFDQAgAC0AEkEEcUUNACAANQJEIQILIAILMwIBfgF/QoCAgIAwIQICQCABEJYDIgNFDQAgAy0AEkEEcUUNACAAIAMoAkAQKSECCyACCygAQoCAgIDgACAAIAMpAwAgARDhBSIAQQBHrUKAgICAEIQgAEEASBsLvAECAX4Cf0KAgICA4AAhBCAAIAEQVQR+QoCAgIDgAAVB9pEBIQICQCABpyIDLwEGEOABRQ0AAkAgAygCICIDLwARIgVBgAhxRQ0AIAMoAlQiBkUNACAAIAYgAygCSBDqAQ8LIAVBBHZBA3FBAWsiA0ECSw0AIANB//8DcUECdEGQ9QFqKAIAIQILIAAgAiAAIAFBNyABQQAQESIBQoCAgIBwg0KAgICAMFEEfiAAQS8QKQUgAQtBnggQsgELC+EFAwN+B38DfAJAIAAgARBVDQAgACAAKQMwQQ4QRyIFQoCAgIBwg0KAgICA4ABRDQAgBaciCSABQoCAgIBwWgR/IAGnLQAFQRBxBUEACyAJLQAFQe8BcXI6AAUCQCAAQQEgAiACQQFMGyIKQQFrIghBA3RBGGoQJCIHRQ0AIAFCIIinQXVPBEAgAaciAiACKAIAQQFqNgIACyAHIAE3AwAgAykDACIEQiCIp0F1TwRAIASnIgIgAigCAEEBajYCAAsgByAINgIQIAcgBDcDCCAHQRhqIQtBACECA0AgAiAIRwRAIAMgAkEBaiIMQQN0aikDACIEQiCIp0F1TwRAIASnIg0gDSgCAEEBajYCAAsgCyACQQN0aiAENwMAIAwhAgwBCwsgCSAHNgIgAn8gAUL/////b1gEQCAAECJBfwwBCyAAQQAgAadBMBBDCyICQQBIDQACQCACRQ0AIAAgAUEwIAFBABARIgRCgICAgHCDQoCAgIDgAFENASAEQv////8PWARAIASnIgIgCGtBACACIApOG60hBgwBCyAEQiCIp0EHa0FtTQRAAkAgBEKAgICAwIGA/P8AfCIEQv///////////wCDQoCAgICAgID4/wBWDQAgBL+dIg8gCLciEGUNACAPIBChIQ4LIA69IgQCfyAOmUQAAAAAAADgQWMEQCAOqgwBC0GAgICAeAsiAre9UQRAIAKtIQYMAgtCgICAgMB+IARCgICAgMCBgPz/AH0gBEL///////////8Ag0KAgICAgICA+P8AVhshBgwBCyAAIAQQDAsgACAFQTAgBkEBEBUaIABBgJIBIAAgAUE3IAFBABARIgFCgICAgHCDIgRCgICAgJB/UgR+IARCgICAgOAAUQ0BIAAgARAMIABBLxApBSABC0HslgEQsgEiAUKAgICAcINCgICAgOAAUQ0AIAAgBUE3IAFBARAVGiAFDwsgACAFEAwLQoCAgIDgAAswACACQQBMBEAgACABQoCAgIAwQQBBABAcDwsgACABIAMpAwAgAkEBayADQQhqEBwLgwICAX4BfyMAQSBrIgIkAEKAgICA4AAhBQJAAkAgACABECAiAUKAgICAcINCgICAgOAAUQ0AIAAgAykDABAw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ARAgCzYAIAMpAwAiAUIgiKciAkF/RiAERSACQX5xQQJHcXJFBEAgABAiQoCAgIDgAA8LIAAgARDoAQuJAQEBfiADKQMAIgFC/////29WIAFCgICAgHCDQoCAgIAgUXJFBEAgAEHe0gBBABASQoCAgIDgAA8LAkAgACABEEEiAUKAgICAcINCgICAgOAAUgRAIAMpAwgiBEKAgICAcINCgICAgDBRDQEgACABIAQQ2gRFDQEgACABEAwLQoCAgIDgAA8LIAELnwIBA34gAUL/////b1gEQCAAECJCgICAgOAADwtCgICAgOAAIQUCfiAAIAFBNyABQQAQESIEQoCAgIBwg0KAgICAMFEEQCAAQZQBECkMAQsgACAEEDQLIgRCgICAgHCDIgZCgICAgOAAUgR+An4gACABQTMgAUEAEBEiAUKAgICAcINCgICAgDBRBEAgAEEvECkMAQsgACABEDQLIgFCgICAgHCDIgVCgICAgOAAUQRAIAAgBBAMQoCAgIDgAA8LAkAgBkKAgICAkH9RBEAgBKcoAgRB/////wdxRQ0BCyAFQoCAgICQf1EEQCABpygCBEH/////B3FFDQELIABB7JYBIARBpJIBELIBIQQLIAAgBCABELYCBUKAgICA4AALC5UCAgF+An8jAEEwayICJABCgICAgOAAIQECQCAAIAJBKGogAykDABCkAQ0AIAAQ4gEiBUKAgICAcINCgICAgOAAUQ0AIAAgAkEUaiADKQMIEK4CIgZFBEAgACAFEAwMAQsgACgC2AEgAhC7ASACQgEQMhogAiACKQMoIgGnIgdBARC5ARogAiACQn9B/////wNBARB6GiAFp0EEaiIDIAYgAhCyBBoCQCAERSABUHINACACQgEQMhogAiAHQQFrQQEQuQEaIAMgAhDyAUEASA0AIAJCARAyGiACIAdBARC5ARogAyADIAJB/////wNBARDuARoLIAIQGSAAIAYgAkEUahDmASAFEK8CIQELIAJBMGokACABCwkAIAAgARDcBAt0AgJ+AX8gACABENwEIgFCgICAgHCDQoCAgIDgAFEEQCABDwtBCiEGAn4CQCACRQ0AIAMpAwAiBEKAgICAcINCgICAgDBRDQAgACAEENsEIgZBAE4NAEKAgICA4AAMAQsgACABIAYQogULIQUgACABEAwgBQvOAQIBfwJ+IwBBEGsiAiQAAkBBuNQEKQMAUA0AQbTUBCgCACAAIAAQPRDqASEDQbTUBCgCACABIAEQPUH9/wAQ8wMiBEHA1AQoAgAQkAMEQEG01AQoAgAgBBAMQbTUBCgCACADEAwMAQsgAiAENwMIIAIgAzcDAEG01AQoAgBBuNQEKQMAQoCAgIAwQQIgAhAcIQNBtNQEKAIAIAIpAwAQDEG01AQoAgAgAikDCBAMIANBwNQEKAIAEJADGkG01AQoAgAgAxAMCyACQRBqJAALPQACfgJAIAEQlgMiAkUNACACLQAQQQFxDQBCgICAgDAgAi0AEUEBcQ0BGgsgAEGTIkEAEBJCgICAgOAACwsSACAAQZMiQQAQEkKAgICA4AAL1w4CB38BfiMAQdAAayIIJAAgCEEAQdAAECwiCCAENgIMIAggADYCACAIQQE2AgggCEKggICAEDcDECAIIAI2AjggCCACIANqIgI2AjwjAEEQayIHJAACQCAIKAI4IgMtAABBI0cNACADLQABQSFHDQAgByADQQJqIgM2AgwDQAJAIAIgA00NAAJAIAMtAAAiCUEKaw4EAQAAAQALIAnAQQBIBEAgA0EGIAdBDGoQUSEJIAcoAgwhAyAJQX5xQajAAEYNASAJQX9HDQILIAcgA0EBaiIDNgIMDAELCyAIIAM2AjgLIAdBEGokAAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAFQQNxIgdBAkYEQCAAKAIQKAKMASILRQ0EIAspAwgiDkL/////b1gNAyAOpyICLwEGEOABRQ0CIAIoAiQhDCACKAIgIgItABAhAwwBCyAFQQN2IQkgB0EBRwR/IAlBA3EFQoCAgIDgACEOIAAgBBC2ASICRQ0MAn8gAEG4ARBcIgNFBEAgACACEBAgAwwBCyADQoCAgIAwNwOwASADQoCAgIAwNwOoASADQoCAgIAwNwNIIANCgICAgDA3A0AgAyACNgIEIANBATYCACADQoCAgIAwNwOYASADQoCAgIAwNwOQASADQoCAgIAwNwOIASAAKALgASICIANBCGoiCjYCBCADIABB4AFqNgIMIAMgAjYCCCAAIAo2AuABIAMLIgpFDQwgCUECcUEBcgshA0EAIQILIABBAEEBQQAgBEEBEOoDIgRFDQcgCCAENgJAIAQgB0ECRyIJNgJMIAQgBzYCJCAEIAVBBnZBAXE2AmgCQCAJRQRAIAQgAi8AEUEGdkEBcTYCUCAEIAIvABFBB3ZBAXE2AlQgBCACLQASQQFxNgJYIAIvABEhByAEQdEANgJwIAQgAzoAbiAEIAdBCXZBAXE2AlwMAQsgBEHRADYCcCAEIAM6AG4gBEKAgICAEDcCWCAEQgA3AlAgAkUNBQsgAigCPCEDIAIvASohByACLwEoIQkgBEEANgLAAiAEQQA2AsgCIAQgAyAHIAlqaiIDNgLEAiADRQ0EIAQgACADQQN0ECQiAzYCyAIgA0UNBQNAIAZBAE4EQCACKAIgIAZBBHRqIAIvAShBBHRqIgMoAgRBAEoEQCAEIAQoAsACIgdBAWo2AsACIAAgBCgCyAIgB0EDdGogAyAGEOkDCyADKAIIIQYMAQsLQQAhAyAGQX5GBEADQCADIAIvASpPDQUCQCACKAIgIANBBHRqIAIvAShBBHRqIgYoAgQNACAGEKYFRQ0AIAQgBCgCwAIiB0EBajYCwAIgACAEKALIAiAHQQN0aiAGIAMQ6QMLIANBAWohAwwACwALA0AgAi8BKCADTQRAQQAhAwNAIAMgAi8BKk8NBgJAIAIoAiAgA0EEdGogAi8BKEEEdGoiBigCBA0AIAYoAgBB0gBGDQAgBCAEKALAAiIHQQFqNgLAAiAAIAQoAsgCIAdBA3RqIAYgAxDpAwsgA0EBaiEDDAALAAUgBCAEKALAAiIGQQFqNgLAAiACKAIgIQcgBCgCyAIgBkEDdGoiBiADOwECIAZBAzoAACAGIAAgByADQQR0aigCABAWNgIEIANBAWohAwwBCwALAAtBxYkBQajsAEHXiwJBmsUAEAAAC0Gk8gBBqOwAQdWLAkGaxQAQAAALQff1AEGo7ABB1IsCQZrFABAAAAtBACEGA0AgBiACKAI8Tg0BIAIoAiQhByAEIAQoAsACIgNBAWo2AsACIAQoAsgCIANBA3RqIgMgAy0AACIJQf4BcToAACADIAcgBkEDdGoiBy0AAEECcSAJQfwBcXIiCToAACADIAlB+gFxIActAABBBHFyIgk6AAAgAyAJQfYBcSAHLQAAQQhxciIJOgAAIActAAAhDSADIAY7AQIgAyAJQQ5xIA1B8AFxcjoAACADIAAgBygCBBAWNgIEIAZBAWohBgwACwALIAQgCjYClAMgBUGAAXEgCnIEQCAEQQI6AGwgBEEBNgJkCyAIIApFNgJIIAggCkEARzYCRCAIEHQaIAQgBCgCvAE2AvABIAgQDw0AIAgQpQUNACAEIAQoAiRBAk8EfyAELQBuQX9zQQFxBUEBCzYCKCAIKAJERQRAIAQgCCgCACAEQdIAEEwiAjYCpAEgAkEASA0BCwNAIAgoAhBBqn9GDQIgCBCkBUUNAAsLIAggCEEQahCBAiAAIAQQ+wIMAQsgCCAIKAJEBH9BAAUgCEHYABANIAgoAkBBgAJqIAQvAaQBECZBAQsQsAIgCgRAIAogBCgCmAM6AFQLIAAgBBCjBSIOQoCAgIBwg0KAgICA4ABRDQAgCgRAIAogDjcDSCAAIAoQ+QNBAEgNAiAKIAooAgBBAWo2AgAgCq1CgICAgFCEIQ4LIAVBIHENAyAAIA4gASAMIAsQtwUhDgwDCyAKRQ0BCyAAIAoQ8gULQoCAgIDgACEOCyAIQdAAaiQAIA4LagIBfwF+QbDUBCgCAARAEIwFC0Gw1AQQ4wUiAjYCACACEO0EIQJBwNQEIAE2AgBBtNQEIAI2AgAgAiAAIAAQPUHR/wAQsgUiAyABEJADBEBBtNQEKAIAIAMQDEEADwtBuNQEIAM3AwBBAQvsAgIDfwF8IwBB0ABrIgQkACAEQRBqQQBBOBAsGiAEQoCAgICAgID4PzcDIEKAgICAwH4hAQJAIAJFDQBBByACIAJBB04bIgJBACACQQBKGyECA0AgAiAFRwRAIAAgBEEIaiADIAVBA3QiBmopAwAQQgRAQoCAgIDgACEBDAMLIAQrAwgiB71CgICAgICAgPj/AINCgICAgICAgPj/AFENAiAEQRBqIAZqIAedOQMAAkAgBQ0AIAQrAxAiB0QAAAAAAAAAAGZFIAdEAAAAAAAAWUBjRXINACAEIAdEAAAAAACwnUCgOQMQCyAFQQFqIQUMAQsLIARBEGpBABDrAyIHvSIBAn8gB5lEAAAAAAAA4EFjBEAgB6oMAQtBgICAgHgLIgW3vVEEQCAFrSEBDAELQoCAgIDAfiABQoCAgIDAgYD8/wB9IAFC////////////AINCgICAgICAgPj/AFYbIQELIARB0ABqJAAgAQtWABCoBSIBQoCAgIAIfEL/////D1gEQCABQv////8Pgw8LQoCAgIDAfiABub0iAUKAgICAwIGA/P8AfSABQv///////////wCDQoCAgICAgID4/wBWGwvvAQEDfiMAQRBrIgIkAEKAgICA4AAhBAJAIAAgACABECAiAUEBELsCIgVCgICAgHCDQoCAgIDgAFENACAFQiCIpyIDQQAgA0ELakESSRtFBEAgACACQQhqIAUQQkEASA0BQoCAgIAgIQQgAikDCEKAgICAgICA+P8Ag0KAgICAgICA+P8AUQ0BC0KAgICA4AAhBCAAIAFB48oAEIcCIgZCgICAgHCDQoCAgIDgAFENACAAIAYQNUUEQCAAQergAEEAEBIgACAGEAwMAQsgACAGIAFBAEEAEDYhBAsgACABEAwgACAFEAwgAkEQaiQAIAQLjAIDAXwBfgF/IwBBEGsiAiQAQoCAgIDgACEFAkAgACACQQhqIgYgARCmAg0AIAAgBiADKQMAEEINACACAn4gAisDCCIEvUKAgICAgICA+P8Ag0KAgICAgICA+P8AUgRAIASdIgREAAAAAACwnUCgIAQgBEQAAAAAAABZQGMbIAQgBEQAAAAAAAAAAGYbIQQLIAS9IgUCfyAEmUQAAAAAAADgQWMEQCAEqgwBC0GAgICAeAsiA7e9UQRAIAOtDAELQoCAgIDAfiAFQoCAgIDAgYD8/wB9IAVC////////////AINCgICAgICAgPj/AFYbCzcDACAAIAFBASACQREQ+AQhBQsgAkEQaiQAIAULigEDAX4BfAF/IwBBEGsiAiQAQoCAgIDgACEEAkAgACACQQhqIgYgARCmAg0AIAAgBiADKQMAEEINACAAIAEgAisDCCIFnUQAAAAAAAAAAKBEAAAAAAAA+H8gBUQAANzCCLI+Q2UbRAAAAAAAAPh/IAVEAADcwgiyPsNmGxD5BCEECyACQRBqJAAgBAvZAQIBfAF+IwBB0ABrIgIkAAJ+QoCAgIDgACAAIAEgAiAEQQ9xQQAQ1QMiAEEASA0AGkKAgICAwH4gAEUNABogBEGAAnEEQCACIAIrAwBEAAAAAACwncCgOQMACyACIARBBHZBD3FBA3RqKwMAIgW9IgECfyAFmUQAAAAAAADgQWMEQCAFqgwBC0GAgICAeAsiBLe9UQRAIAStDAELQoCAgIDAfiABQoCAgIDAgYD8/wB9IAFC////////////AINCgICAgICAgPj/AFYbCyEGIAJB0ABqJAAgBguHAQIBfAF+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IAMpAxAiBUIgiKdBdU8EQCAFpyIJIAkoAgBBAWo2AgALIAggBTcDCAJAIAQNACADKQMYIgVCIIinQXVJDQAgBaciCSAJKAIAQQFqNgIACyAIIAE3AxAgCCAFNwMAIAAgByAGQQMgCBAcIQUgACAIKQMAEAwgBEUEQCAAIAgpAwgQDAsgAygCBCEDIAAoAhAgAhDiAyAFQoCAgIBwg0KAgICA4ABRDQIgACAFEAwLDAALAAsgCEEgaiQAIAULVAAgACABIAJBImoQWiIARQRAQoCAgIDgAA8LIAAoAgwiAEEATgRAIACtDwtCgICAgMB+IAC4vSIBQoCAgIDAgYD8/wB9IAFCgICAgICAgPj/AFYbC1kBAX8gACABIARBImoQWiICRQRAQoCAgIDgAA8LIAJBBGohAyACKAIIIQQDfiADIARGBH5CgICAgDAFIARBEGshBSAEKAIEIQQgACgCECACIAUQgAUMAQsLC3UAIAAgASAEQSJqEFoiAkUEQEKAgICA4AAPCyAAIAIgAykDACIBQgAgAUIgiKdBB2tBbk8bIAEgAUKAgICAwIGA/P8AfEL///////////8Ag1AbEPICIgNFBEBCgICAgBAPCyAAKAIQIAIgAxCABUKBgICAEAthACAAIAEgBEEiahBaIgJFBEBCgICAgOAADwsgACACIAMpAwAiAUIAIAFCIIinQQdrQW5PGyABIAFCgICAgMCBgPz/AHxC////////////AINQGxDyAkEAR61CgICAgBCECwgAQoCAgIAwC0oAAkAgBSkDACIBQoCAgIBwVA0AIAGnIgIvAQZBLEcNACACKAIgIgJFDQAgAkEBOgARIAAgARAMIAVCgICAgCA3AwALQoCAgIAwC88BAQN+IwBBEGsiAiQAQoCAgIDgACEFAkACQAJ+QoCAgIAwIABCgICAgDAgACADEMAEIgRCgICAgHCDQoCAgIDgAFENABogAiAENwMIQoCAgIDgACAAQcMAQQBBAEEBIAJBCGoQhQEiBkKAgICAcINCgICAgOAAUQ0AGiAAEDMiAUKAgICAcINCgICAgOAAUg0BIAYLIQEgACAEEAwgACABEAwMAQsgACABQYQBIARBBxAVGiAAIAFBhQEgBkEHEBUaIAEhBQsgAkEQaiQAIAULswMCA38CfiMAQdAAayIGJABBfyEHAkAgACAG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QoCAgIBwg0KAgICA4ABRcg0AIAAgAykDCCIGEDVFDQBCgICAgOAAIQQCQCAAEDMiBUKAgICAcINCgICAgOAAUQRAIAEhBQwBCyAAIAVBLyABQQcQFUEASA0AIAAgBUEvIAYQhQUhBAsgACAFEAwMAQsgASEECyAHQRBqJAAgBAsQACAAIAMpAwBBESAEELICC6UDAQR+IwBBEGsiAyQAIAQCfwJAAkACQAJAIAAgAUEqEFoiAkUEQEKAgICAMCEBDAELIAIoAhgEQEKAgICAMCEBQQEMBQsgACACKQMAIgggAikDCCIGEMUBIgFCgICAgHCDIgdCgICAgOAAUg0BC0KAgICAMCEHDAELIAdCgICAgCBRBEAgAkEBNgIYQoCAgIAwIQFBAQwDCyACKAIQBEAgACAAIAFCABBOEDQiB0KAgICAcIMiCUKAgICA4ABRDQECQCAJQoCAgICQf1INACAHpygCBEH/////B3ENACAAIANBCGogACAIQdYAIAhBABAREKEBQQBIDQIgACAIQdYAAn4gBqcgAykDCCACKAIUEPQCIgZCgICAgAh8Qv////8PWARAIAZC/////w+DDAELQoCAgIDAfiAGub0iBkKAgICAwIGA/P8AfSAGQv///////////wCDQoCAgICAgID4/wBWGwsQOUEASA0CCyAAIAcQDAwCCyACQQE2AhgMAQsgACABEAwgACAHEAxCgICAgOAAIQELQQALNgIAIANBEGokACABCyAAIAFCIIinQXVPBEAgAaciACAAKAIAQQFqNgIACyABC/EHAgR/C34jAEEwayIEJAACQCABQv////9vWARAIAAQIkKAgICA4AAhAQwBC0KAgICAMCEIAkACQCAAIAMpAwAQJSIPQoCAgIBwg0KAgICA4ABRBEBCgICAgDAhDEKAgICAMCEBQoCAgIAwIQ1CgICAgDAhEAwBCyAAIAEgACkDSBD9ASIQQoCAgIBwg0KAgICA4ABRBEBCgICAgDAhDEKAgICAMCEBQoCAgIAwIQ0MAQsCQAJAIAAgACABQe4AIAFBABAREDQiDUKAgICAcINCgICAgOAAUQ0AIA2nIgJB9QBBABCgASEGIAJB+QBBABCgAUEASARAIABB7JYBIA1B0A4QsgEiDUKAgICAcINCgICAgOAAUQ0BCyAEIA03AyggBCABNwMgIAAgEEECIARBIGoQowEiDEKAgICAcINCgICAgOAAUQ0BIAAQOyIBQoCAgIBwg0KAgICA4ABRBEBCgICAgOAAIQEMAwtBfyECAkAgAykDCCIJQoCAgIBwg0KAgICAMFENACAAIARBHGogCRB1QQBIDQMgBCgCHCICDQAMBAsCQAJAIA+nIgcpAgQiCKdB/////wdxIgUEQCAGQX9zQR92IQYgCEL/////B4MhESACrSESQgAhCUKAgICAMCEIQQAhAgNAIAKtIQogAiEDA0AgAyAFTw0DIAAgDEHWACADrSIOEDlBAEgNByAAIAgQDAJAIAAgDCAPEMUBIghCgICAgHCDIgtCgICAgCBRDQAgC0KAgICA4ABRDQggACAEQRBqIAAgDEHWACAMQQAQERChAQ0IIAQgBCkDECILIBEgCyARUxsiCzcDECAKIAtRDQAgACAHIAIgAxCOASIKQoCAgIBwg0KAgICA4ABRDQggACABIAkgChBnQQBIDQggCUIBfCIKIBJRDQkgACAEQQhqIAgQLw0IIAunIQJCASELIAlCASAEKQMIIg4gDkIBVxt8IQkDQCAJIApRDQMgACAAIAggCxBsEDQiDkKAgICAcINCgICAgOAAUQ0JIAAgASAKIA4QZ0EASA0JIAtCAXwhCyAKQgF8IgogElINAAsMCQsgByAOIAYQ9AKnIQMMAAsACwALIAAgDCAPEMUBIghCgICAgHCDIglCgICAgCBSDQFCACEJQQAhAgsgACAHIAIgBSACIAVJGyAFEI4BIgpCgICAgHCDQoCAgIDgAFENAyAAIAEgCSAKEGdBAEgNAwwECyAJQoCAgIDgAFINAwwCC0KAgICAMCEMC0KAgICAMCEBCyAAIAEQDEKAgICA4AAhAQsgACAPEAwgACAQEAwgACAMEAwgACANEAwgACAIEAwLIARBMGokACABC+ACAQd+IAFC/////29YBEAgABAiQoCAgIDgAA8LQoCAgIDgACEIQoCAgIAwIQYCQAJAAkAgACADKQMAECUiB0KAgICAcINCgICAgOAAUQRAQoCAgIAwIQQMAQsgACABQdYAIAFBABARIgRCgICAgHCDQoCAgIDgAFENACAAIARCABBNRQRAIAAgAUHWAEIAEDlBAEgNAQsgACABIAcQxQEiBUKAgICAcIMiCUKAgICA4ABRDQEgACABQdYAIAFBABARIgZCgICAgHCDQoCAgIDgAFENAQJAIAAgBiAEEE0EQCAAIAQQDAwBCyAAIAFB1gAgBBA5QQBODQBCgICAgDAhBAwCCyAAIAcQDCAAIAYQDEL/////DyEIIAlCgICAgCBRDQIgACAFQdgAIAVBABARIQogACAFEAwgCg8LQoCAgIAwIQULIAAgBRAMIAAgBxAMIAAgBhAMIAAgBBAMCyAIC84EAgZ+AX8jAEEgayICJAACQCABQv////9vWARAIAAQIkKAgICA4AAhBwwBC0KAgICA4AAhB0KAgICAMCEIAkAgACADKQMAECUiCUKAgICAcINCgICAgOAAUQRAQoCAgIAwIQRCgICAgDAhBUKAgICAMCEGDAELAkACQCAAIAEgACkDSBD9ASIGQoCAgIBwg0KAgICA4ABRBEBCgICAgDAhBAwBCyAAIAAgAUHuACABQQAQERA0IgRCgICAgHCDQoCAgIDgAFINAQtCgICAgDAhBQwBCyACIAQ3AxggAiABNwMQIAAgBkECIAJBEGoQowEiBUKAgICAcINCgICAgOAAUQ0AIAAgAkEIaiAAIAFB1gAgAUEAEBEQoQENACAAIAVB1gACfiACKQMIIgFCgICAgAh8Qv////8PWARAIAFC/////w+DDAELQoCAgIDAfiABub0iAUKAgICAwIGA/P8AfSABQv///////////wCDQoCAgICAgID4/wBWGwsQOUEASA0AQoCAgIDgACEIIABBKhCGASIBQoCAgIBwg0KAgICA4ABRDQAgAEEgECQiA0UEQCABIQgMAQsgAyAJNwMIIAMgBTcDACADIASnIgpB5wBBABCgAUF/c0EfdjYCECAKQfUAQQAQoAEhCiADQQA2AhggAyAKQX9zQR92NgIUIAFCgICAgHBaBEAgAacgAzYCIAsgACAGEAwgACAEEAwgASEHDAELIAAgCRAMIAAgBhAMIAAgBBAMIAAgBRAMIAAgCBAMCyACQSBqJAAgBwv+BAIIfgJ/IwBBEGsiAiQAAkAgAUL/////b1gEQCAAECJCgICAgOAAIQcMAQtCgICAgOAAIQdCgICAgDAhBQJAAkACQCAAIAMpAwAQJSIJQoCAgIBwg0KAgICA4ABRBEBCgICAgDAhCAwBCyAAIAFB7gAgAUEAEBEiCEKAgICAcINCgICAgOAAUQ0AIAAgCBA0IghCgICAgHCDQoCAgIDgAFENACAIp0HnAEEAEKABQX9GBEAgACABIAkQxQEhBwwDCyAAIAAgAUHwACABQQAQERAnIgxBAEgNACAAIAFB1gBCABA5QQBIDQAgABA7IgZCgICAgHCDQoCAgIDgAFEEQEKAgICA4AAhBgwCCyAJpyENA0ACQCAAIAUQDCAAIAEgCRDFASIFQoCAgIBwgyIEQoCAgIAgUQ0AIARCgICAgOAAUQ0DAkAgACAAIAVCABBOEDQiBEKAgICAcIMiC0KAgICAkH9SBEBBACEDIAtCgICAgOAAUQ0FDAELIASnKAIEQf////8HcUUhAwsgACAGIAogBBB7QQBIDQMgCkIBfCEKIANFDQEgACACQQhqIAAgAUHWACABQQAQERChAUEASA0DIAAgAUHWAAJ+IA0gAikDCCAMEPQCIgRCgICAgAh8Qv////8PWARAIARC/////w+DDAELQoCAgIDAfiAEub0iBEKAgICAwIGA/P8AfSAEQv///////////wCDQoCAgICAgID4/wBWGwsQOUEATg0BDAMLCyAKpwRAIAYhBwwDCyAAIAYQDEKAgICAICEHDAILQoCAgIAwIQYLIAAgBhAMCyAAIAUQDCAAIAgQDCAAIAkQDAsgAkEQaiQAIAcLjgEBAn8gASgCACICQQBKBEAgASACQQFrIgI2AgACQCACDQAgAS0ABEHwAXFBEEcNACABKAIIIgIgASgCDCIDNgIEIAMgAjYCACABQQA2AgggACgCYCICIAFBCGoiAzYCBCABIABB4ABqNgIMIAEgAjYCCCAAIAM2AmALDwtB5oQBQajsAEHWLEHN4wAQAAAL8BQCDn8OfiMAQZABayIEJAACQCABQv////9vWARAIAAQIkKAgICA4AAhFQwBCyADKQMIIR4gACAEQThqQQAQPhogBEEANgIwIARCgICAgMAANwMoIAQgADYCACAEIARBCGoiBzYCBEKAgICA4AAhFUKAgICAMCEWQoCAgIAwIRdCgICAgDAhE0KAgICAMCEUQoCAgIAwIR1CgICAgDAhHAJAAkAgACADKQMAECUiGEKAgICAcINCgICAgOAAUQ0AIAAgHhA1IglFBEAgACAeECUiHUKAgICAcINCgICAgOAAUQ0BIB2nIQULAkACQCAAIAFB7gAgAUEAEBEiHEKAgICA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QQRqIQMMAAsACwuaAQEHfyABpygCICIDBEAgAEEQaiEEIANBBGohBiADKAIIIQIDQCACIAZHBEAgAigCBCEIIAJBEGshBSACQQxrKAIARQRAAkAgAygCAARAIAUQnAUMAQsgACACKQMQECELIAAgAikDGBAhCyAEIAUgACgCBBEAACAIIQIMAQsLIAQgAygCECAAKAIEEQAAIAQgAyAAKAIEEQAACwsbAQF/IAGnKAIgIgMEQCAAIAMoAgwgAhEAAAsLUgEDfyABpygCICICBEAgAigCBCIDBEAgAigCACIEIAM2AgQgAyAENgIAIAJCADcCAAsgACACNQIMQoCAgIBwhBAhIABBEGogAiAAKAIEEQAACwupAQEGfyABpygCICIDBEAgA0EMaiEFIAMoAhAhAgNAIAIgBUcEQCACKAIEIQcgAkIANwIAIAIoAgghBCAHIQIgBC8BBkEgRg0BIARCADcCJAwBCwsCQAJAIAMtAAVFDQAgACgCyAEiAkUNACAAKALQASADKAIIIAIRAAAMAQsgAygCGCICRQ0AIAAgAygCFCADKAIIIAIRBgALIABBEGogAyAAKAIEEQAACwspAQF/IAAgAaciAjUCJEKAgICAkH+EECEgACACNQIgQoCAgICQf4QQIQshACABpygCICkDACIBQoCAgIBgWgRAIAAgAacgAhEAAAsLaQEDfyAAIAGnKAIgIgIpAwAQISACLQARRQRAA0AgAigCFCEEIAMgAigCDE9FBEAgACAEIANBA3RqKAIEEMcBIANBAWohAwwBCwsgAEEQaiAEIAAoAgQRAAALIABBEGogAiAAKAIEEQAAC2wBA38CQCABQoCAgIBwVA0AIAGnIgMvAQZBD0cNACADKAIgIgRFDQAgBEEIaiEFQQAhAwNAIAMgBC0ABU8NASAFIANBA3RqKQMAIgFCgICAgGBaBEAgACABpyACEQAACyADQQFqIQMMAAsACwtqAQN/AkAgAUKAgICAcFQNACABpyICLwEGQQ9HDQAgAigCICIDRQ0AIANBCGohBEEAIQIDQCACIAMtAAVPRQRAIAAgBCACQQN0aikDABAhIAJBAWohAgwBCwsgAEEQaiADIAAoAgQRAAALC38BA38gAacoAiAiBCkDACIBQoCAgIBgWgRAIAAgAacgAhEAAAsgBCkDCCIBQoCAgIBgWgRAIAAgAacgAhEAAAsgBEEYaiEFA0AgBCgCECADSgRAIAUgA0EDdGopAwAiAUKAgICAYFoEQCAAIAGnIAIRAAALIANBAWohAwwBCwsLWQEDfyAAIAGnKAIgIgIpAwAQISAAIAIpAwgQISACQRhqIQQDQCADIAIoAhBORQRAIAAgBCADQQN0aikDABAhIANBAWohAwwBCwsgAEEQaiACIAAoAgQRAAALcgEEfyABpyIDKAIgIQQgAygCJCEFIAMoAigiAwRAIAAgAyACEQAACyAEBEACQCAFRQ0AQQAhAwNAIAMgBCgCPE4NASAFIANBAnRqKAIAIgYEQCAAIAYgAhEAAAsgA0EBaiEDDAALAAsgACAEIAIRAAALC3wBA38gAaciAigCKCIDBEAgACADrUKAgICAcIQQIQsgAigCICIDBEAgAigCJCIEBEBBACECA0AgAiADKAI8TkUEQCAAIAQgAkECdGooAgAQ5QEgAkEBaiECDAELCyAAQRBqIAQgACgCBBEAAAsgACADrUKAgICAYIQQIQsLEgAgAacoAiAiAARAIAAQngMLCx4AIAGnKQMgIgFCgICAgGBaBEAgACABpyACEQAACwsZACAAIAGnIgApAyAQISAAQoCAgIAwNwMgC0QBAn8gAachBANAIAQoAiggA0sEQCAEKAIkIANBA3RqKQMAIgFCgICAgGBaBEAgACABpyACEQAACyADQQFqIQMMAQsLC0YBA38gAachAwNAIAMoAiQhBCACIAMoAihPRQRAIAAgBCACQQN0aikDABAhIAJBAWohAgwBCwsgAEEQaiAEIAAoAgQRAAALEQAgAEEQaiACIAAoAgQRAAAL2wECAX8CfiMAQSBrIgMkACABQQNGBEAgAikDECEEIAIpAwghBQJAIAAgA0EQaiACKQMAEKoFQQBIBEBCgICAgOAAIQQMAQsgACAEIAVBAiADQRBqEBwiBEKAgICAcINCgICAgOAAUQRAIAAoAhAiASkDgAEhBCABQoCAgIAgNwOAASADIAQ3AwggACADKQMYQoCAgIAwQQEgA0EIahAcIQQgACADKQMIEAwLIAAgAykDEBAMIAAgAykDGBAMCyADQSBqJAAgBA8LQZuCAUGo7ABBy/UCQaDtABAAAAuIAQIBfgF/QQAhAkKAgICAMCEBA0ACQCACQQJHBH4gBSACQQN0IgRq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Y29kZV0KfQBjYW5ub3QgbWl4ID8/IHdpdGggJiYgb3IgfHwAcHJveHk6IHByb3BlcnR5IG5vdCBwcmVzZW50IGluIHRhcmdldCB3ZXJlIHJldHVybmVkIGJ5IG5vbiBleHRlbnNpYmxlIHByb3h5AHJldm9rZWQgcHJveHkAUHJveHkAYWRkX3Byb3BlcnR5AHByb3h5OiBjYW5ub3Qgc2V0IHByb3BlcnR5AG5vIHNldHRlciBmb3IgcHJvcGVydHkAdmFsdWUgaGFzIG5vIHByb3BlcnR5AGNvdWxkIG5vdCBkZWxldGUgcHJvcGVydHkAcHJveHk6IGR1cGxpY2F0ZSBwcm9wZXJ0eQBKU19EZWZpbmVBdXRvSW5pdFByb3BlcnR5AGhhc093blByb3BlcnR5AHByb3h5OiBpbmNvbnNpc3RlbnQgZGVsZXRlUHJvcGVydHkAcHJveHk6IGluY29uc2lzdGVudCBkZWZpbmVQcm9wZXJ0eQBKU19EZWZpbmVQcm9wZXJ0eQAhbXItPmVtcHR5AGluZmluaXR5AEluZmluaXR5AG91dCBvZiBtZW1vcnkAdW5rbm93biB1bmljb2RlIGdlbmVyYWwgY2F0ZWdvcnkAR2VuZXJhbF9DYXRlZ29yeQBldmVyeQBhbnkAYXBwbHkAJyVzJyBpcyByZWFkLW9ubHkAZXhwZWN0aW5nIGNhdGNoIG9yIGZpbmFsbHkAc3RpY2t5AGJpZ2ludCBhcmUgZm9yYmlkZGVuIGluIEpTT04uc3RyaW5naWZ5AHN1YmFycmF5AGVtcHR5IGFycmF5AG5vbiBpbnRlZ2VyIGluZGV4IGluIHR5cGVkIGFycmF5AG5lZ2F0aXZlIGluZGV4IGluIHR5cGVkIGFycmF5AG91dC1vZi1ib3VuZCBpbmRleCBpbiB0eXBlZCBhcnJheQBjYW5ub3QgY3JlYXRlIG51bWVyaWMgaW5kZXggaW4gdHlwZWQgYXJyYXkAaXNBcnJheQBUeXBlZEFycmF5AGdldERheQBnZXRVVENEYXkAZ3JvdXBCeQBtLT5kZnNfYW5jZXN0b3JfaW5kZXggPD0gbS0+ZGZzX2luZGV4AGpzX2dldF9hdG9tX2luZGV4AGludmFsaWQgYXJyYXkgaW5kZXgASlNfQXRvbUlzQXJyYXlJbmRleABmaW5kTGFzdEluZGV4AGZpbmRJbmRleABpbnZhbGlkIGV4cG9ydCBzeW50YXgAaW52YWxpZCBhc3NpZ25tZW50IHN5bnRheABtYXgAXHUlMDR4AGludmFsaWQgb3Bjb2RlOiBwYz0ldSBvcGNvZGU9MHglMDJ4AC0rICAgMFgweAAtMFgrMFggMFgtMHgrMHggMHgAbGluZSB0ZXJtaW5hdG9yIG5vdCBhbGxvd2VkIGFmdGVyIHRocm93AGJmX3BvdwBub3cAaW50ZWdlciBvdmVyZmxvdwBzdGFjayBvdmVyZmxvdwBtdXN0IGJlIGNhbGxlZCB3aXRoIG5ldwBpc1ZpZXcARGF0YVZpZXcAcmF3ACV1AGNsYXNzIGRlY2xhcmF0aW9ucyBjYW4ndCBhcHBlYXIgaW4gc2luZ2xlLXN0YXRlbWVudCBjb250ZXh0AGZ1bmN0aW9uIGRlY2xhcmF0aW9ucyBjYW4ndCBhcHBlYXIgaW4gc2luZ2xlLXN0YXRlbWVudCBjb250ZXh0AGxleGljYWwgZGVjbGFyYXRpb25zIGNhbid0IGFwcGVhciBpbiBzaW5nbGUtc3RhdGVtZW50IGNvbnRleHQAZHVwbGljYXRlIGFyZ3VtZW50IG5hbWVzIG5vdCBhbGxvd2VkIGluIHRoaXMgY29udGV4dABkdXBsaWNhdGUgcGFyYW1ldGVyIG5hbWVzIG5vdCBhbGxvd2VkIGluIHRoaXMgY29udGV4dABpbXBvcnQubWV0YSBub3Qgc3VwcG9ydGVkIGluIHRoaXMgY29udGV4dABKU19GcmVlQ29udGV4dABKU0NvbnRleHQAanNfbWFwX2l0ZXJhdG9yX25leHQAanNfZ2VuZXJhdG9yX25leHQAanNfYXN5bmNfZ2VuZXJhdG9yX3Jlc3VtZV9uZXh0AHVuZXhwZWN0ZWQgZW5kIG9mIGlucHV0AHR0AGV4cG9ydGVkIHZhcmlhYmxlICclcycgZG9lcyBub3QgZXhpc3QAcHJpdmF0ZSBjbGFzcyBmaWVsZCAnJXMnIGRvZXMgbm90IGV4aXN0AHRlc3QAYXNzaWdubWVudCByZXN0IHByb3BlcnR5IG11c3QgYmUgbGFzdABwdmFsID09IGxhc3QAZmluZExhc3QAYmZfc3FydABzb3J0AGNicnQAdHJpbVN0YXJ0AHBhZFN0YXJ0AHVua25vd24gdW5pY29kZSBzY3JpcHQAU2NyaXB0AGh5cG90AGZyZWVfemVyb19yZWZjb3VudABzdHJfaW5kZXggPT0gbnVtX2tleXNfY291bnQgKyBzdHJfa2V5c19jb3VudABudW1faW5kZXggPT0gbnVtX2tleXNfY291bnQAc3ltX2luZGV4ID09IGF0b21fY291bnQAbGFiZWwgPj0gMCAmJiBsYWJlbCA8IHMtPmxhYmVsX2NvdW50AGxhYjEgPj0gMCAmJiBsYWIxIDwgcy0+bGFiZWxfY291bnQAdmFsIDwgcy0+Y2FwdHVyZV9jb3VudAB2YWwyIDwgcy0+Y2FwdHVyZV9jb3VudABpbnZhbGlkIHJlcGVhdCBjb3VudABpbnZhbGlkIHJlcGV0aXRpb24gY291bnQAZm9udABpbnZhbGlkIGNvZGUgcG9pbnQAZnJvbUNvZGVQb2ludABpbnZhbGlkIGhpbnQAY2Fubm90IGNvbnZlcnQgTmFOIG9yIEluZmluaXR5IHRvIGJpZ2ludABjYW5ub3QgY29udmVydCB0byBiaWdpbnQAYm90aCBvcGVyYW5kcyBtdXN0IGJlIGJpZ2ludABub3QgYSBiaWdpbnQAcHJpdmF0ZSBtZXRob2QgaXMgYWxyZWFkeSBwcmVzZW50AGVuY29kZVVSSUNvbXBvbmVudABkZWNvZGVVUklDb21wb25lbnQAdW5leHBlY3RlZCBlbmQgb2YgY29tbWVudABpbnZhbGlkIHN3aXRjaCBzdGF0ZW1lbnQAQmlnSW50AHBhcnNlSW50AGR1cGxpY2F0ZSBkZWZhdWx0AHNwbGl0AGV4cGVjdGluZyBoZXggZGlnaXQAdHJpbVJpZ2h0AHJlZHVjZVJpZ2h0AHVuc2hpZnQAdHJpbUxlZnQAaW52YWxpZCBvZmZzZXQAaW52YWxpZCBieXRlT2Zmc2V0AGdldFRpbWV6b25lT2Zmc2V0AHJlc29sdmluZyBmdW5jdGlvbiBhbHJlYWR5IHNldABwcm94eTogaW5jb25zaXN0ZW50IHNldABmaW5kX2p1bXBfdGFyZ2V0AGV4cGVjdGluZyB0YXJnZXQAaW52YWxpZCBkZXN0cnVjdHVyaW5nIHRhcmdldABwcm94eTogaW5jb25zaXN0ZW50IGdldABXZWFrU2V0AGNvbnN0cnVjdABKU19GcmVlQXRvbVN0cnVjdAB1c2Ugc3RyaWN0AFJlZmxlY3QAcmVqZWN0AG5vdCBhbiBBc3luY0dlbmVyYXRvciBvYmplY3QAY2Fubm90IGNvbnZlcnQgdG8gb2JqZWN0AGludmFsaWQgYnJhbmQgb24gb2JqZWN0AG9wZXJhbmQgJ3Byb3RvdHlwZScgcHJvcGVydHkgaXMgbm90IGFuIG9iamVjdABpdGVyYXRvciBtdXN0IHJldHVybiBhbiBvYmplY3QAbm90IGEgRGF0ZSBvYmplY3QAbm90IGEgb2JqZWN0AEpTT2JqZWN0AHBhcnNlRmxvYXQAZmxhdABub3RoaW5nIHRvIHJlcGVhdABjb25jYXQAY29kZVBvaW50QXQAY2hhckF0AGNoYXJDb2RlQXQAa2V5cwBwcm94eTogdGFyZ2V0IHByb3BlcnR5IG11c3QgYmUgcHJlc2VudCBpbiBwcm94eSBvd25LZXlzACAgZmFzdCBhcnJheXMAZXhwb3J0ICclcycgaW4gbW9kdWxlICclcycgaXMgYW1iaWd1b3VzAHByaXZhdGUgY2xhc3MgZmllbGQgJyVzJyBhbHJlYWR5IGV4aXN0cwB0b28gbWFueSBhcmd1bWVudHMAVG9vIG1hbnkgY2FsbCBhcmd1bWVudHMAdG9vIG1hbnkgZWxlbWVudHMAICBlbGVtZW50cwBpbnZhbGlkIG51bWJlciBvZiBkaWdpdHMAYmluYXJ5IG9iamVjdHMAaW52YWxpZCBwcm9wZXJ0eSBhY2Nlc3MAanNfb3BfZGVmaW5lX2NsYXNzAGZkLT5ieXRlX2NvZGUuYnVmW2RlZmluZV9jbGFzc19wb3NdID09IE9QX2RlZmluZV9jbGFzcwBfX2dldENsYXNzAHNldEhvdXJzAGdldEhvdXJzAHNldFVUQ0hvdXJzAGdldFVUQ0hvdXJzAGdhdGhlcl9hdmFpbGFibGVfYW5jZXN0b3JzAGdldE93blByb3BlcnR5RGVzY3JpcHRvcnMAd2l0aFJlc29sdmVycwB0b28gbWFueSBpbWJyaWNhdGVkIHF1YW50aWZpZXJzAHVuaWNvZGVfcHJvcF9vcHMAYWNvcwBmb3IgYXdhaXQgaXMgb25seSB2YWxpZCBpbiBhc3luY2hyb25vdXMgZnVuY3Rpb25zAG5ldy50YXJnZXQgb25seSBhbGxvd2VkIHdpdGhpbiBmdW5jdGlvbnMAYnl0ZWNvZGUgZnVuY3Rpb25zAEMgZnVuY3Rpb25zAHByb3h5OiBpbmNvbnNpc3RlbnQgcHJldmVudEV4dGVuc2lvbnMAU2NyaXB0X0V4dGVuc2lvbnMAYXRvbXMAcHJveHk6IHByb3BlcnRpZXMgbXVzdCBiZSBzdHJpbmdzIG9yIHN5bWJvbHMAZ2V0T3duUHJvcGVydHlTeW1ib2xzAHJlc29sdmVfbGFiZWxzAEpTX0V2YWxUaGlzAHN0cmluZ3MAaW52YWxpZCBkZXNjcmlwdG9yIGZsYWdzAGludmFsaWQgcmVndWxhciBleHByZXNzaW9uIGZsYWdzAHZhbHVlcwBzZXRNaW51dGVzAGdldE1pbnV0ZXMAc2V0VVRDTWludXRlcwBnZXRVVENNaW51dGVzAHRvbyBtYW55IGNhcHR1cmVzACAgc2hhcGVzAGdldE93blByb3BlcnR5TmFtZXMAZ2NfZnJlZV9jeWNsZXMAYWRkX2V2YWxfdmFyaWFibGVzAHJlc29sdmVfdmFyaWFibGVzAHRvbyBtYW55IGxvY2FsIHZhcmlhYmxlcwB0b28gbWFueSBjbG9zdXJlIHZhcmlhYmxlcwBjb21wYWN0X3Byb3BlcnRpZXMAICBwcm9wZXJ0aWVzAGRlZmluZVByb3BlcnRpZXMAZW50cmllcwBmcm9tRW50cmllcwB0b28gbWFueSByYW5nZXMAaW5jbHVkZXMAaGFzSW5kaWNlcwBzZXRNaWxsaXNlY29uZHMAZ2V0TWlsbGlzZWNvbmRzAHNldFVUQ01pbGxpc2Vjb25kcwBnZXRVVENNaWxsaXNlY29uZHMAc2V0U2Vjb25kcwBnZXRTZWNvbmRzAHNldFVUQ1NlY29uZHMAZ2V0VVRDU2Vjb25kcwBpdGFsaWNzAGFicwBwcm94eTogaW5jb25zaXN0ZW50IGhhcwAlLipzACAoJXMAc2V0ICVzAGdldCAlcwAgICAgYXQgJXMAbm90IGEgJXMAdW5zdXBwb3J0ZWQga2V5d29yZDogJXMAc3Vic3RyAHByb3h5OiBpbmNvbnNpc3RlbnQgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yAHN1cGVyKCkgaXMgb25seSB2YWxpZCBpbiBhIGRlcml2ZWQgY2xhc3MgY29uc3RydWN0b3IAcGFyZW50IGNsYXNzIG11c3QgYmUgY29uc3RydWN0b3IAbm90IGEgY29uc3RydWN0b3IAQXJyYXkgSXRlcmF0b3IAU2V0IEl0ZXJhdG9yAE1hcCBJdGVyYXRvcgBSZWdFeHAgU3RyaW5nIEl0ZXJhdG9yAG5vdCBhbiBBc3luYy1mcm9tLVN5bmMgSXRlcmF0b3IAY2Fubm90IGludm9rZSBhIHJ1bm5pbmcgZ2VuZXJhdG9yAG5vdCBhIGdlbmVyYXRvcgBBc3luY0dlbmVyYXRvcgBzeW50YXggZXJyb3IAU3ludGF4RXJyb3IARXZhbEVycm9yAEludGVybmFsRXJyb3IAQWdncmVnYXRlRXJyb3IAVHlwZUVycm9yAFJhbmdlRXJyb3IAUmVmZXJlbmNlRXJyb3IAVVJJRXJyb3IAZmxvb3IAZm9udGNvbG9yAGFuY2hvcgBmb3IAa2V5Rm9yAGV4cGVjdGluZyBzdXJyb2dhdGUgcGFpcgBhIGRlY2xhcmF0aW9uIGluIHRoZSBoZWFkIG9mIGEgZm9yLSVzIGxvb3AgY2FuJ3QgaGF2ZSBhbiBpbml0aWFsaXplcgAnYXJndW1lbnRzJyBpZGVudGlmaWVyIGlzIG5vdCBhbGxvd2VkIGluIGNsYXNzIGZpZWxkIGluaXRpYWxpemVyAGludmFsaWQgbnVtYmVyIG9mIGFyZ3VtZW50cyBmb3IgZ2V0dGVyIG9yIHNldHRlcgBpbnZhbGlkIHNldHRlcgBpbnZhbGlkIGdldHRlcgBmaWx0ZXIAbWlzc2luZyBmb3JtYWwgcGFyYW1ldGVyACJ1c2Ugc3RyaWN0IiBub3QgYWxsb3dlZCBpbiBmdW5jdGlvbiB3aXRoIGRlZmF1bHQgb3IgZGVzdHJ1Y3R1cmluZyBwYXJhbWV0ZXIAaW52YWxpZCBjaGFyYWN0ZXIAdW5leHBlY3RlZCBjaGFyYWN0ZXIAcHJpdmF0ZSBjbGFzcyBmaWVsZCBmb3JiaWRkZW4gYWZ0ZXIgc3VwZXIAaW52YWxpZCByZWRlZmluaXRpb24gb2YgbGV4aWNhbCBpZGVudGlmaWVyACdsZXQnIGlzIG5vdCBhIHZhbGlkIGxleGljYWwgaWRlbnRpZmllcgBpbnZhbGlkIHJlZGVmaW5pdGlvbiBvZiBnbG9iYWwgaWRlbnRpZmllcgB5aWVsZCBpcyBhIHJlc2VydmVkIGlkZW50aWZpZXIAJyVzJyBpcyBhIHJlc2VydmVkIGlkZW50aWZpZXIAb3RoZXIAYXRvbTFfaXNfaW50ZWdlciAmJiBhdG9tMl9pc19pbnRlZ2VyAGNhbm5vdCBjb252ZXJ0IHRvIGJpZ2ludDogbm90IGFuIGludGVnZXIAaXNJbnRlZ2VyAGlzU2FmZUludGVnZXIAYnVmZmVyAFNoYXJlZEFycmF5QnVmZmVyAGNhbm5vdCB1c2UgaWRlbnRpY2FsIEFycmF5QnVmZmVyAGNhbm5vdCBjb252ZXJ0IGJpZ2ludCB0byBudW1iZXIAY2Fubm90IGNvbnZlcnQgc3ltYm9sIHRvIG51bWJlcgBub3QgYSBudW1iZXIAbGluZU51bWJlcgBtYWxmb3JtZWQgdW5pY29kZSBjaGFyAGNsZWFyAHNldFllYXIAZ2V0WWVhcgBzZXRGdWxsWWVhcgBnZXRGdWxsWWVhcgBzZXRVVENGdWxsWWVhcgBnZXRVVENGdWxsWWVhcgBxICE9IHIAdW5leHBlY3RlZCBsaW5lIHRlcm1pbmF0b3IgaW4gcmVnZXhwAHVuZXhwZWN0ZWQgZW5kIG9mIHJlZ2V4cABSZWdFeHAAc3VwAGludmFsaWQgZ3JvdXAAcG9wAGNvbnRpbnVlIG11c3QgYmUgaW5zaWRlIGxvb3AAYmZfbG9naWNfb3AAZHVtcABudW1fa2V5c19jbXAAdXNlIHN0cmlwAG1hcABmbGF0TWFwAFdlYWtNYXAAZXhwZWN0aW5nICd7JyBhZnRlciBccABsb2cxcABkaXZpc2lvbiBieSB6ZXJvADBvAGhhc093bgByZXR1cm4AcHJvbWlzZSBzZWxmIHJlc29sdXRpb24Ab3V0IG9mIG1lbW9yeSBpbiByZWdleHAgZXhlY3V0aW9uAGRlc2NyaXB0aW9uACFtLT5ldmFsX2hhc19leGNlcHRpb24AIW1vZHVsZS0+ZXZhbF9oYXNfZXhjZXB0aW9uAHByb3h5OiBkZWZpbmVQcm9wZXJ0eSBleGNlcHRpb24AanNfYXN5bmNfZ2VuZXJhdG9yX3Jlc29sdmVfZnVuY3Rpb24AanNfY3JlYXRlX2Z1bmN0aW9uAHNldC9hZGQgaXMgbm90IGEgZnVuY3Rpb24AcmV0dXJuIG5vdCBpbiBhIGZ1bmN0aW9uAEFzeW5jR2VuZXJhdG9yRnVuY3Rpb24AY2FsbEV4dGVybmFsRnVuY3Rpb24AQXN5bmNGdW5jdGlvbgBqc19pbm5lcl9tb2R1bGVfZXZhbHVhdGlvbgAhbS0+YXN5bmNfZXZhbHVhdGlvbgBtb2R1bGUtPmFzeW5jX2V2YWx1YXRpb24AaW52YWxpZCBvcGVyYXRpb24AdW5zdXBwb3J0ZWQgb3BlcmF0aW9uAGF3YWl0IGluIGRlZmF1bHQgZXhwcmVzc2lvbgB5aWVsZCBpbiBkZWZhdWx0IGV4cHJlc3Npb24AaW52YWxpZCBkZWNpbWFsIGVzY2FwZSBpbiByZWd1bGFyIGV4cHJlc3Npb24AYmFjayByZWZlcmVuY2Ugb3V0IG9mIHJhbmdlIGluIHJlZ3VsYXIgZXhwcmVzc2lvbgBpbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZSBpbiByZWd1bGFyIGV4cHJlc3Npb24AZXhwZWN0ZWQgJ29mJyBvciAnaW4nIGluIGZvciBjb250cm9sIGV4cHJlc3Npb24AdG9vIGNvbXBsaWNhdGVkIGRlc3RydWN0dXJpbmcgZXhwcmVzc2lvbgBleHBlY3RlZCAnfScgYWZ0ZXIgdGVtcGxhdGUgZXhwcmVzc2lvbgB0b1ByZWNpc2lvbgBhc2luAGpvaW4AbWluAGNvcHlXaXRoaW4AdGVtcGxhdGUgbGl0ZXJhbCBjYW5ub3QgYXBwZWFyIGluIGFuIG9wdGlvbmFsIGNoYWluAGNpcmN1bGFyIHByb3RvdHlwZSBjaGFpbgBhc3NpZ24AIXktPnNpZ24AaXNGcm96ZW4AKHBvcyArIGxlbikgPD0gYmNfYnVmX2xlbgB1bmV4cGVjdGVkIGVsbGlwc2lzIHRva2VuAHRoZW4Ac2V0dGVyIGlzIGZvcmJpZGRlbgBudWxsIG9yIHVuZGVmaW5lZCBhcmUgZm9yYmlkZGVuAGF0YW4AbmFuAG5vdCBhIGJvb2xlYW4AQm9vbGVhbgBnY19zY2FuAGJhZCBub3JtYWxpemF0aW9uIGZvcm0ASlNfTmV3U3ltYm9sRnJvbUF0b20AZnJvbQByYW5kb20AdHJpbQBiZl9kaXZyZW0AbS0+Y3ljbGVfcm9vdCA9PSBtAGltdWwAbm90IGEgc3ltYm9sAFN5bWJvbABSZWdFeHAgZXhlYyBtZXRob2QgbXVzdCByZXR1cm4gYW4gb2JqZWN0IG9yIG51bGwAcGFyZW50IHByb3RvdHlwZSBtdXN0IGJlIGFuIG9iamVjdCBvciBudWxsAGNhbm5vdCBzZXQgcHJvcGVydHkgJyVzJyBvZiBudWxsAGNhbm5vdCByZWFkIHByb3BlcnR5ICclcycgb2YgbnVsbABOdWxsAGZpbGwAbmV3IEFycmF5QnVmZmVyIGlzIHRvbyBzbWFsbABUeXBlZEFycmF5IGxlbmd0aCBpcyB0b28gc21hbGwAY2FsbABkb3RBbGwAbWF0Y2hBbGwAcmVwbGFjZUFsbABjZWlsAHVwZGF0ZV9sYWJlbABiY19idWZbcG9zXSA9PSBPUF9sYWJlbABldmFsAGludmFsaWQgYmlnaW50IGxpdGVyYWwAaW52YWxpZCBudW1iZXIgbGl0ZXJhbABtYWxmb3JtZWQgZXNjYXBlIHNlcXVlbmNlIGluIHN0cmluZyBsaXRlcmFsAGJmX2V4cF9pbnRlcm5hbABiZl9sb2dfaW50ZXJuYWwAYmZfZnRvYV9pbnRlcm5hbABKU19TZXRQcm9wZXJ0eUludGVybmFsAEpTX0dldE93blByb3BlcnR5TmFtZXNJbnRlcm5hbABfX0pTX0V2YWxJbnRlcm5hbAB0b0V4cG9uZW50aWFsAHNlYWwAZ2xvYmFsAGJsaW5rAHJldHVybiBpbiBhIHN0YXRpYyBpbml0aWFsaXplciBibG9jawBzdGFjawBscmVfZXhlY19iYWNrdHJhY2sAcy0+aXNfd2VhawBiZl9wb3dfdWkAc2V0TW9udGgAZ2V0TW9udGgAc2V0VVRDTW9udGgAZ2V0VVRDTW9udGgAaW52YWxpZCBrZXl3b3JkOiB3aXRoAHN0YXJ0c1dpdGgAZW5kc1dpdGgAcHJvcCA9PSBKU19BVE9NX2xlbmd0aABpbnZhbGlkIGFycmF5IGxlbmd0aABpbnZhbGlkIGFycmF5IGJ1ZmZlciBsZW5ndGgAaW52YWxpZCBsZW5ndGgAaW52YWxpZCBieXRlTGVuZ3RoAE1hdGgAcHVzaABhY29zaABKU19SZXNpemVBdG9tSGFzaABhc2luaABhdGFuaABicmVhayBtdXN0IGJlIGluc2lkZSBsb29wIG9yIHN3aXRjaABtYXRjaABuaXBfY2F0Y2gAc2VhcmNoAGZvckVhY2gAYmZfbG9nAEFycmF5IHRvbyBsb25nAHN0cmluZyB0b28gbG9uZwBBcnJheSBsb28gbG9uZwBzdWJzdHJpbmcAY2Fubm90IGNvbnZlcnQgc3ltYm9sIHRvIHN0cmluZwB1bmV4cGVjdGVkIGVuZCBvZiBzdHJpbmcAbm90IGEgc3RyaW5nAGludmFsaWQgY2hhcmFjdGVyIGluIGEgSlNPTiBzdHJpbmcAdG9TdHJpbmcAdG9EYXRlU3RyaW5nAHRvTG9jYWxlRGF0ZVN0cmluZwB0b1RpbWVTdHJpbmcAdG9Mb2NhbGVUaW1lU3RyaW5nAHRvTG9jYWxlU3RyaW5nAHRvR01UU3RyaW5nAEpTU3RyaW5nAHRvSVNPU3RyaW5nAHRvVVRDU3RyaW5nAGpzX2lubmVyX21vZHVsZV9saW5raW5nAGR1cGxpY2F0ZSBpbXBvcnQgYmluZGluZwBpbnZhbGlkIGltcG9ydCBiaW5kaW5nAHByb21pc2UgaXMgcGVuZGluZwBiaWcAcmVnZXhwIG11c3QgaGF2ZSB0aGUgJ2cnIGZsYWcAb2YAaW5mAEluZgBkaWZmID09IChpbnQ4X3QpZGlmZgBkaWZmID09IChpbnQxNl90KWRpZmYAaHJlZgBnY19kZWNyZWYAZnJlZV92YXJfcmVmAG9wdGltaXplX3Njb3BlX21ha2VfZ2xvYmFsX3JlZgByZXNldF93ZWFrX3JlZgBkZWxldGVfd2Vha19yZWYAb3B0aW1pemVfc2NvcGVfbWFrZV9yZWYAaW5kZXhPZgBsYXN0SW5kZXhPZgB2YWx1ZU9mAHNldFByb3RvdHlwZU9mAGdldFByb3RvdHlwZU9mAGlzUHJvdG90eXBlT2YAJS4qZgBmb250c2l6ZQBuZXdfc2l6ZSA8PSBzaC0+cHJvcF9zaXplAGRlc2NyIDwgcnQtPmF0b21fc2l6ZQBhdG9tIDwgcnQtPmF0b21fc2l6ZQBjb21wdXRlX3N0YWNrX3NpemUAbiA8IGJ1Zl9zaXplAG5vcm1hbGl6ZQBjcl9yZWdleHBfY2Fub25pY2FsaXplAGZyZWV6ZQByZXNvbHZlAHRvUHJpbWl0aXZlAHB1dF9sdmFsdWUAdW5rbm93biB1bmljb2RlIHByb3BlcnR5IHZhbHVlAHJlc3QgZWxlbWVudCBjYW5ub3QgaGF2ZSBhIGRlZmF1bHQgdmFsdWUAaW52YWxpZCByZXQgdmFsdWUAX19KU19BdG9tVG9WYWx1ZQBfX3F1b3RlAGlzRmluaXRlAGRlbGV0ZQBjcmVhdGUAc2V0RGF0ZQBnZXREYXRlAHNldFVUQ0RhdGUAZ2V0VVRDRGF0ZQBJbnZhbGlkIERhdGUAcmV2ZXJzZQBwYXJzZQBwcm94eSBwcmV2ZW50RXh0ZW5zaW9ucyBoYW5kbGVyIHJldHVybmVkIGZhbHNlAG1vZHVsZSBuYW1lc3BhY2UgcHJvcGVydGllcyBoYXZlIHdyaXRhYmxlID0gZmFsc2UAUHJvbWlzZQB0b0xvd2VyQ2FzZQB0b0xvY2FsZUxvd2VyQ2FzZQB0b1VwcGVyQ2FzZQB0b0xvY2FsZVVwcGVyQ2FzZQBpZ25vcmVDYXNlAGxvY2FsZUNvbXBhcmUAcHJveHk6IGluY29uc2lzdGVudCBwcm90b3R5cGUAcHJveHk6IGJhZCBwcm90b3R5cGUAbm90IGEgcHJvdG90eXBlAGludmFsaWQgb2JqZWN0IHR5cGUAdW5lc2NhcGUAbm9uZQByZXN0IGVsZW1lbnQgbXVzdCBiZSB0aGUgbGFzdCBvbmUAbXVsdGlsaW5lACAgcGMybGluZQBhc3luY19mdW5jX3Jlc3VtZQBzb21lAEpTX0ZyZWVSdW50aW1lAEpTUnVudGltZQBzZXRUaW1lAGdldFRpbWUAYXN5bmNfZnVuY19mcmVlX2ZyYW1lAHNldF9vYmplY3RfbmFtZQBleHBlY3RpbmcgcHJvcGVydHkgbmFtZQB1bmtub3duIHVuaWNvZGUgcHJvcGVydHkgbmFtZQBpbnZhbGlkIHByb3BlcnR5IG5hbWUAZHVwbGljYXRlIF9fcHJvdG9fXyBwcm9wZXJ0eSBuYW1lAGludmFsaWQgcmVkZWZpbml0aW9uIG9mIHBhcmFtZXRlciBuYW1lAGV4cGVjdGluZyBncm91cCBuYW1lAGR1cGxpY2F0ZSBncm91cCBuYW1lAGludmFsaWQgZ3JvdXAgbmFtZQBkdXBsaWNhdGUgbGFiZWwgbmFtZQBpbnZhbGlkIGZpcnN0IGNoYXJhY3RlciBvZiBwcml2YXRlIG5hbWUAaW52YWxpZCBsZXhpY2FsIHZhcmlhYmxlIG5hbWUAaW52YWxpZCBtZXRob2QgbmFtZQBleHBlY3RpbmcgZmllbGQgbmFtZQBpbnZhbGlkIGZpZWxkIG5hbWUAY2xhc3Mgc3RhdGVtZW50IHJlcXVpcmVzIGEgbmFtZQBmaWxlTmFtZQBqc19saW5rX21vZHVsZQBqc19ldmFsdWF0ZV9tb2R1bGUAbW9kdWxlLT5jeWNsZV9yb290ID09IG1vZHVsZQBjb21waWxlAG9iamVjdCBpcyBub3QgZXh0ZW5zaWJsZQBwcm94eTogaW5jb25zaXN0ZW50IGlzRXh0ZW5zaWJsZQBjYW5ub3QgaGF2ZSBzZXR0ZXIvZ2V0dGVyIGFuZCB2YWx1ZSBvciB3cml0YWJsZQBwcm9wZXJ0eSBpcyBub3QgY29uZmlndXJhYmxlAHZhbHVlIGlzIG5vdCBpdGVyYWJsZQBwcm9wZXJ0eUlzRW51bWVyYWJsZQBtaXNzaW5nIGluaXRpYWxpemVyIGZvciBjb25zdCB2YXJpYWJsZQBsZXhpY2FsIHZhcmlhYmxlAGludmFsaWQgcmVkZWZpbml0aW9uIG9mIGEgdmFyaWFibGUAcmV2b2NhYmxlAHN0cmlrZQBtcF9kaXZub3JtX2xhcmdlAGludmFsaWQgY2xhc3MgcmFuZ2UAbWVzc2FnZQBpbnZhbGlkIGx2YWx1ZSBpbiBzdHJpY3QgbW9kZQBpbnZhbGlkIHZhcmlhYmxlIG5hbWUgaW4gc3RyaWN0IG1vZGUAY2Fubm90IGRlbGV0ZSBhIGRpcmVjdCByZWZlcmVuY2UgaW4gc3RyaWN0IG1vZGUAb2N0YWwgZXNjYXBlIHNlcXVlbmNlcyBhcmUgbm90IGFsbG93ZWQgaW4gc3RyaWN0IG1vZGUAb2N0YWwgbGl0ZXJhbHMgYXJlIGRlcHJlY2F0ZWQgaW4gc3RyaWN0IG1vZGUAdW5pY29kZQAgIGJ5dGVjb2RlAEpTRnVuY3Rpb25CeXRlY29kZQBza2lwX2RlYWRfY29kZQBpbnZhbGlkIGFyZ3VtZW50IG5hbWUgaW4gc3RyaWN0IGNvZGUAaW52YWxpZCBmdW5jdGlvbiBuYW1lIGluIHN0cmljdCBjb2RlAGludmFsaWQgcmVkZWZpbml0aW9uIG9mIGdsb2JhbCBpZGVudGlmaWVyIGluIG1vZHVsZSBjb2RlAGltcG9ydC5tZXRhIG9ubHkgdmFsaWQgaW4gbW9kdWxlIGNvZGUAZnJvbUNoYXJDb2RlAGludmFsaWQgZm9yIGluL29mIGxlZnQgaGFuZC1zaWRlAGludmFsaWQgYXNzaWdubWVudCBsZWZ0LWhhbmQgc2lkZQByZWR1Y2UAc291cmNlACd0aGlzJyBjYW4gYmUgaW5pdGlhbGl6ZWQgb25seSBvbmNlAHByb3BlcnR5IGNvbnN0cnVjdG9yIGFwcGVhcnMgbW9yZSB0aGFuIG9uY2UAaW52YWxpZCBVVEYtOCBzZXF1ZW5jZQBjaXJjdWxhciByZWZlcmVuY2UAc2xpY2UAc3BsaWNlAHJhY2UAcmVwbGFjZQAlKy4qZQB1bmV4cGVjdGVkICdhd2FpdCcga2V5d29yZAB1bmV4cGVjdGVkICd5aWVsZCcga2V5d29yZABtYXBfZGVjcmVmX3JlY29yZABpdGVyYXRvciBkb2VzIG5vdCBoYXZlIGEgdGhyb3cgbWV0aG9kAG9iamVjdCBuZWVkcyB0b0lTT1N0cmluZyBtZXRob2QAJ3N1cGVyJyBpcyBvbmx5IHZhbGlkIGluIGEgbWV0aG9kAGZyb3VuZABfX2JmX3JvdW5kAGJyZWFrL2NvbnRpbnVlIGxhYmVsIG5vdCBmb3VuZABvdXQgb2YgYm91bmQAZmluZABiaW5kAGludmFsaWQgaW5kZXggZm9yIGFwcGVuZABleHRyYW5lb3VzIGNoYXJhY3RlcnMgYXQgdGhlIGVuZAB1bmV4cGVjdGVkIGRhdGEgYXQgdGhlIGVuZAB1bmV4cGVjdGVkIGVuZABpbnZhbGlkIGluY3JlbWVudC9kZWNyZW1lbnQgb3BlcmFuZABpbnZhbGlkICdpbnN0YW5jZW9mJyByaWdodCBvcGVyYW5kAGludmFsaWQgJ2luJyBvcGVyYW5kAHRyaW1FbmQAcGFkRW5kAGJvbGQAJWxsZABnY19kZWNyZWZfY2hpbGQAcmVzb2x2ZV9zY29wZV9wcml2YXRlX2ZpZWxkAGNhbm5vdCBkZWxldGUgYSBwcml2YXRlIGNsYXNzIGZpZWxkAGV4cGVjdGluZyA8YnJhbmQ+IHByaXZhdGUgZmllbGQAJXMgaXMgbm90IGluaXRpYWxpemVkAGZpeGVkAHRvRml4ZWQAc2V0X29iamVjdF9uYW1lX2NvbXB1dGVkAHJlZ2V4IG5vdCBzdXBwb3J0ZWQAZXZhbCBpcyBub3Qgc3VwcG9ydGVkAFJlZ0V4cCBhcmUgbm90IHN1cHBvcnRlZAB0b1NvcnRlZABpbnRlcnJ1cHRlZAAhcy0+aXNfY29tcGxldGVkACVzIG9iamVjdCBleHBlY3RlZABpZGVudGlmaWVyIGV4cGVjdGVkAGJ5dGVjb2RlIGZ1bmN0aW9uIGV4cGVjdGVkAHN0cmluZyBleHBlY3RlZABmcm9tIGNsYXVzZSBleHBlY3RlZABmdW5jdGlvbiBuYW1lIGV4cGVjdGVkAHZhcmlhYmxlIG5hbWUgZXhwZWN0ZWQAbWV0YSBleHBlY3RlZABqc19hc3luY19tb2R1bGVfZXhlY3V0aW9uX3JlamVjdGVkAGpzX3NldF9tb2R1bGVfZXZhbHVhdGVkAG1lbW9yeSBhbGxvY2F0ZWQAbWVtb3J5IHVzZWQAdG9SZXZlcnNlZABkZXJpdmVkIGNsYXNzIGNvbnN0cnVjdG9yIG11c3QgcmV0dXJuIGFuIG9iamVjdCBvciB1bmRlZmluZWQAY2Fubm90IHNldCBwcm9wZXJ0eSAnJXMnIG9mIHVuZGVmaW5lZABjYW5ub3QgcmVhZCBwcm9wZXJ0eSAnJXMnIG9mIHVuZGVmaW5lZABmbGFncyBtdXN0IGJlIHVuZGVmaW5lZABVbmRlZmluZWQAcHJpdmF0ZSBjbGFzcyBmaWVsZCBpcyBhbHJlYWR5IGRlZmluZWQAJyVzJyBpcyBub3QgZGVmaW5lZABncm91cCBuYW1lIG5vdCBkZWZpbmVkAGlzV2VsbEZvcm1lZAB0b1dlbGxGb3JtZWQAYWxsU2V0dGxlZABqc19hc3luY19tb2R1bGVfZXhlY3V0aW9uX2Z1bGZpbGxlZABjYW5ub3QgYmUgY2FsbGVkAGlzU2VhbGVkACFzaC0+aXNfaGFzaGVkAEFycmF5QnVmZmVyIGlzIGRldGFjaGVkAGpzX2FycmF5X3RvU3BsaWNlZABhZGQAJSswN2QAJTA0ZAAlMDJkJTAyZABwJStkACVjJStkACUwMmQvJTAyZC8lMCpkACUuM3MgJS4zcyAlMDJkICUwKmQAcCVkACVjJWQAOiVkAGludmFsaWQgdGhyb3cgdmFyIHR5cGUgJWQAc2MAanNfZGVmX21hbGxvYwB0cnVuYwBnYwBleGVjAGJmX2ludGVnZXJfdG9fcmFkaXhfcmVjAC90bXAvcXVpY2tqcy9xdWlja2pzLmMAL3RtcC9xdWlja2pzL2xpYnJlZ2V4cC5jAC90bXAvcXVpY2tqcy9saWJiZi5jAC90bXAvcXVpY2tqcy9saWJ1bmljb2RlLmMAc3ViAHByb21pc2VfcmVhY3Rpb25fam9iAGpzX3Byb21pc2VfcmVzb2x2ZV90aGVuYWJsZV9qb2IAMGIAciAhPSBhICYmIHIgIT0gYgBxICE9IGEgJiYgcSAhPSBiAHJ3YQByICE9IGEAX19sb29rdXBTZXR0ZXJfXwBfX2RlZmluZVNldHRlcl9fAF9fbG9va3VwR2V0dGVyX18AX19kZWZpbmVHZXR0ZXJfXwBfX3Byb3RvX18AW1N5bWJvbC5zcGxpdF0AW1N5bWJvbC5zcGVjaWVzXQBbU3ltYm9sLml0ZXJhdG9yXQBbU3ltYm9sLmFzeW5jSXRlcmF0b3JdAFtTeW1ib2wubWF0Y2hBbGxdAFtTeW1ib2wubWF0Y2hdAFtTeW1ib2wuc2VhcmNoXQBbU3ltYm9sLnRvU3RyaW5nVGFnXQBbU3ltYm9sLnRvUHJpbWl0aXZlXQBbdW5zdXBwb3J0ZWQgdHlwZV0AW2Z1bmN0aW9uIGJ5dGVjb2RlXQBbU3ltYm9sLmhhc0luc3RhbmNlXQBbU3ltYm9sLnJlcGxhY2VdAFsAJTAyZDolMDJkOiUwMmQuJTAzZFoAUE9TSVRJVkVfSU5GSU5JVFkATkVHQVRJVkVfSU5GSU5JVFkAcC0+Y2xhc3NfaWQgPT0gSlNfQ0xBU1NfQVJSQVkAc3RhY2tfbGVuIDwgUE9QX1NUQUNLX0xFTl9NQVgALSUwMmQtJTAyZFQASlNfQXRvbUdldFN0clJUAG9wY29kZSA8IFJFT1BfQ09VTlQASlNfVkFMVUVfR0VUX1RBRyhmdW5jX3JldCkgPT0gSlNfVEFHX0lOVABCWVRFU19QRVJfRUxFTUVOVAAlMDJkOiUwMmQ6JTAyZCBHTVQASlNfVkFMVUVfR0VUX1RBRyhzZi0+Y3VyX2Z1bmMpID09IEpTX1RBR19PQkpFQ1QAdmFyX2tpbmQgPT0gSlNfVkFSX1BSSVZBVEVfU0VUVEVSAE1BWF9TQUZFX0lOVEVHRVIATUlOX1NBRkVfSU5URUdFUgBhc1VpbnROAGFzSW50TgBpc05hTgBEYXRlIHZhbHVlIGlzIE5hTgB0b0pTT04ARVBTSUxPTgBwLT5nY19vYmpfdHlwZSA9PSBKU19HQ19PQkpfVFlQRV9KU19PQkpFQ1QgfHwgcC0+Z2Nfb2JqX3R5cGUgPT0gSlNfR0NfT0JKX1RZUEVfRlVOQ1RJT05fQllURUNPREUgfHwgcC0+Z2Nfb2JqX3R5cGUgPT0gSlNfR0NfT0JKX1RZUEVfQVNZTkNfRlVOQ1RJT04ATkFOACUwMmQ6JTAyZDolMDJkICVjTQBzdGFja190b3AgPT0gTlVMTABzLT5sYWJlbF9zbG90c1tsYWJlbF0uZmlyc3RfcmVsb2MgPT0gTlVMTABsYWJlbF9zbG90c1tpXS5maXJzdF9yZWxvYyA9PSBOVUxMAHBycyAhPSBOVUxMAHNmLT5jdXJfc3AgIT0gTlVMTABzZiAhPSBOVUxMAG1yMSAhPSBOVUxMAHZhcl9raW5kICE9IEpTX1ZBUl9OT1JNQUwAYi0+ZnVuY19raW5kID09IEpTX0ZVTkNfTk9STUFMAGVuY29kZVVSSQBkZWNvZGVVUkkAUEkAc3BlY2lhbCA9PSBQVVRfTFZBTFVFX05PS0VFUCB8fCBzcGVjaWFsID09IFBVVF9MVkFMVUVfTk9LRUVQX0RFUFRIAHMtPnN0YXRlID09IEpTX0FTWU5DX0dFTkVSQVRPUl9TVEFURV9FWEVDVVRJTkcAbTEtPnN0YXR1cyA9PSBKU19NT0RVTEVfU1RBVFVTX0VWQUxVQVRJTkcAbTEtPnN0YXR1cyA9PSBKU19NT0RVTEVfU1RBVFVTX0xJTktJTkcAcHJlYyAhPSBCRl9QUkVDX0lORgBwcmVjMSAhPSBCRl9QUkVDX0lORgAwMTIzNDU2Nzg5QUJDREVGAFNJWkUATUFYX1ZBTFVFAE1JTl9WQUxVRQBOQU1FAGV2YWxfdHlwZSA9PSBKU19FVkFMX1RZUEVfR0xPQkFMIHx8IGV2YWxfdHlwZSA9PSBKU19FVkFMX1RZUEVfTU9EVUxFAExPRzJFAExPRzEwRQBzLT5zdGF0ZSA9PSBKU19BU1lOQ19HRU5FUkFUT1JfU1RBVEVfQVdBSVRJTkdfUkVUVVJOIHx8IHMtPnN0YXRlID09IEpTX0FTWU5DX0dFTkVSQVRPUl9TVEFURV9DT01QTEVURUQAbS0+c3RhdHVzID09IEpTX01PRFVMRV9TVEFUVVNfVU5MSU5LRUQgfHwgbS0+c3RhdHVzID09IEpTX01PRFVMRV9TVEFUVVNfTElOS0VEIHx8IG0tPnN0YXR1cyA9PSBKU19NT0RVTEVfU1RBVFVTX0VWQUxVQVRJTkdfQVNZTkMgfHwgbS0+c3RhdHVzID09IEpTX01PRFVMRV9TVEFUVVNfRVZBTFVBVEVEAG0xLT5zdGF0dXMgPT0gSlNfTU9EVUxFX1NUQVRVU19FVkFMVUFUSU5HIHx8IG0xLT5zdGF0dXMgPT0gSlNfTU9EVUxFX1NUQVRVU19FVkFMVUFUSU5HX0FTWU5DIHx8IG0xLT5zdGF0dXMgPT0gSlNfTU9EVUxFX1NUQVRVU19FVkFMVUFURUQAbTEtPnN0YXR1cyA9PSBKU19NT0RVTEVfU1RBVFVTX0xJTktJTkcgfHwgbTEtPnN0YXR1cyA9PSBKU19NT0RVTEVfU1RBVFVTX0xJTktFRCB8fCBtMS0+c3RhdHVzID09IEpTX01PRFVMRV9TVEFUVVNfRVZBTFVBVElOR19BU1lOQyB8fCBtMS0+c3RhdHVzID09IEpTX01PRFVMRV9TVEFUVVNfRVZBTFVBVEVEAG0tPnN0YXR1cyA9PSBKU19NT0RVTEVfU1RBVFVTX0xJTktFRABtLT5zdGF0dXMgPT0gSlNfTU9EVUxFX1NUQVRVU19VTkxJTktFRABVVEMAbS0+c3RhdHVzID09IEpTX01PRFVMRV9TVEFUVVNfRVZBTFVBVElOR19BU1lOQwBtb2R1bGUtPnN0YXR1cyA9PSBKU19NT0RVTEVfU1RBVFVTX0VWQUxVQVRJTkdfQVNZTkMAPGlucHV0PgA8aW5pdFNjcmlwdD4APGV2YWxTY3JpcHQ+ADxzZXQ+ADxhbm9ueW1vdXM+ADxjb21tRnVuPgA8Y2FsbEV4dGVybmFsRnVuY3Rpb24+ADxudWxsPgBiaWdpbnQgb3BlcmFuZHMgYXJlIGZvcmJpZGRlbiBmb3IgPj4+ACZxdW90OwBzZXRVaW50OABnZXRVaW50OABzZXRJbnQ4AGdldEludDgAbWFsZm9ybWVkIFVURi04AHJhZGl4IG11c3QgYmUgYmV0d2VlbiAyIGFuZCAzNgBzZXRVaW50MTYAZ2V0VWludDE2AHNldEludDE2AGdldEludDE2AGFyZ2MgPT0gNQBzZXRCaWdVaW50NjQAZ2V0QmlnVWludDY0AHNldEJpZ0ludDY0AGdldEJpZ0ludDY0AHNldEZsb2F0NjQAZ2V0RmxvYXQ2NABhcmdjID09IDMAYXRhbjIAbG9nMgBTUVJUMV8yAFNRUlQyAExOMgBjbHozMgBzZXRVaW50MzIAZ2V0VWludDMyAHNldEludDMyAGdldEludDMyAHNldEZsb2F0MzIAZ2V0RmxvYXQzMgBzdGFja19sZW4gPj0gMgBKU19BdG9tSXNOdW1lcmljSW5kZXgxAGpzX2ZjdnQxAEpTX0NvbXBhY3RCaWdJbnQxAGV4cG0xAHIgIT0gYTEgJiYgciAhPSBiMQBscy0+YWRkciA9PSAtMQBucSA+PSAxAHN0YWNrX2xlbiA+PSAxAHAtPmhlYWRlci5yZWZfY291bnQgPT0gMQBwLT5zaGFwZS0+aGVhZGVyLnJlZl9jb3VudCA9PSAxAHN0YWNrX2xlbiA9PSAxAGpzX2ZyZWVfc2hhcGUwAGxvZzEwAExOMTAAcC0+cmVmX2NvdW50ID4gMAB2YXJfcmVmLT5oZWFkZXIucmVmX2NvdW50ID4gMABtLT5wZW5kaW5nX2FzeW5jX2RlcGVuZGVuY2llcyA+IDAAc3RhY2tfc2l6ZSA+IDAAY3Bvb2xfaWR4ID49IDAAcnQtPmF0b21fY291bnQgPj0gMABscy0+cmVmX2NvdW50ID49IDAAcy0+aXNfZXZhbCB8fCBzLT5jbG9zdXJlX3Zhcl9jb3VudCA9PSAwAHAtPnJlZl9jb3VudCA9PSAwAGN0eC0+aGVhZGVyLnJlZl9jb3VudCA9PSAwAHNoLT5oZWFkZXIucmVmX2NvdW50ID09IDAAcC0+bWFyayA9PSAwAChwci0+dS5pbml0LnJlYWxtX2FuZF9pZCAmIDMpID09IDAAKG5ld19oYXNoX3NpemUgJiAobmV3X2hhc2hfc2l6ZSAtIDEpKSA9PSAwAGkgIT0gMABzaXplICE9IDAAXiRcLiorPygpW117fXwvADwvADAuAG1pc3NpbmcgYmluZGluZyBwYXR0ZXJuLi4uAGJpZ2ludCBhcmd1bWVudCB3aXRoIHVuYXJ5ICsAYXN5bmMgZnVuY3Rpb24gKgAKfSkAbGlzdF9lbXB0eSgmcnQtPmdjX29ial9saXN0KQBqID09IChzaC0+cHJvcF9jb3VudCAtIHNoLT5kZWxldGVkX3Byb3BfY291bnQpACFfX0pTX0F0b21Jc1RhZ2dlZEludChkZXNjcikAIWF0b21faXNfZnJlZShwKQAobnVsbCkAIChuYXRpdmUpAGpzX2NsYXNzX2hhc19ieXRlY29kZShwLT5jbGFzc19pZCkAbmlwX2NhdGNoOiBubyBjYXRjaCBvcCAocGM9JWQpAGluY29uc2lzdGVudCBjYXRjaCBwb3NpdGlvbjogJWQgJWQgKHBjPSVkKQBpbmNvbnNpc3RlbnQgc3RhY2sgc2l6ZTogJWQgJWQgKHBjPSVkKQBieXRlY29kZSBidWZmZXIgb3ZlcmZsb3cgKG9wPSVkLCBwYz0lZCkAc3RhY2sgb3ZlcmZsb3cgKG9wPSVkLCBwYz0lZCkAc3RhY2sgdW5kZXJmbG93IChvcD0lZCwgcGM9JWQpAGludmFsaWQgb3Bjb2RlIChvcD0lZCwgcGM9JWQpACg/OikAaWR4IDwgY291bnRvZihjYXNlX2NvbnZfdGFibGUxKQBubyBmdW5jdGlvbiBmaWxlbmFtZSBmb3IgaW1wb3J0KCkALV8uIX4qJygpACBhbm9ueW1vdXMoAFN5bWJvbCgAZXhwZWN0aW5nICd9JwBjbGFzcyBjb25zdHJ1Y3RvcnMgbXVzdCBiZSBpbnZva2VkIHdpdGggJ25ldycAZXhwZWN0aW5nICdhcycAdW5leHBlY3RlZCB0b2tlbiBpbiBleHByZXNzaW9uOiAnJS4qcycAdW5leHBlY3RlZCB0b2tlbjogJyUuKnMnAHJlZGVjbGFyYXRpb24gb2YgJyVzJwBkdXBsaWNhdGUgZXhwb3J0ZWQgbmFtZSAn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XwAAcF8AAAwLBQQCAgAAuwAAAHoAAAB7AAAAvAAAAHwAAAB9AAAAvQAAAHwAAAB9AAAAvgAAAFIAAABTAAAAvwAAAH4AAAB/AAAAwAAAAH4AAAB/AAAALwAAAIAAAACBAAAAwQAAAFIAAABTAAAAwgAAAIIAAACDAAAAAAAAAOkWAAAaFwAAJRcAAN0WAAAQFwAANBcAAPMWAAABFwAAY29weVdpdGhpbgBlbnRyaWVzAGZpbGwAZmluZABmaW5kSW5kZXgAZmluZExhc3QAZmluZExhc3RJbmRleABmbGF0AGZsYXRNYXAAaW5jbHVkZXMAa2V5cwB0b1JldmVyc2VkAHRvU29ydGVkAHRvU3BsaWNlZAB2YWx1ZXMAAAAAAAEBAgIDAwIDAAAAAAAAbnVsbABmYWxzZQB0cnVlAGlmAGVsc2UAcmV0dXJuAHZhcgB0aGlzAGRlbGV0ZQB2b2lkAHR5cGVvZgBuZXcAaW4AaW5zdGFuY2VvZgBkbwB3aGlsZQBmb3IAYnJlYWsAY29udGludWUAc3dpdGNoAGNhc2UAZGVmYXVsdAB0aHJvdwB0cnkAY2F0Y2gAZmluYWxseQBmdW5jdGlvbgBkZWJ1Z2dlcgB3aXRoAGNsYXNzAGNvbnN0AGVudW0AZXhwb3J0AGV4dGVuZHMAaW1wb3J0AHN1cGVyAGltcGxlbWVudHMAaW50ZXJmYWNlAGxldABwYWNrYWdlAHByaXZhdGUAcHJvdGVjdGVkAHB1YmxpYwBzdGF0aWMAeWllbGQAYXdhaXQAAGxlbmd0aABmaWxlTmFtZQBsaW5lTnVtYmVyAG1lc3NhZ2UAY2F1c2UAZXJyb3JzAHN0YWNrAG5hbWUAdG9TdHJpbmcAdG9Mb2NhbGVTdHJpbmcAdmFsdWVPZgBldmFsAHByb3RvdHlwZQBjb25zdHJ1Y3RvcgBjb25maWd1cmFibGUAd3JpdGFibGUAZW51bWVyYWJsZQB2YWx1ZQBnZXQAc2V0AG9mAF9fcHJvdG9fXwB1bmRlZmluZWQAbnVtYmVyAGJvb2xlYW4Ac3RyaW5nAG9iamVjdABzeW1ib2wAaW50ZWdlcgB1bmtub3duAGFyZ3VtZW50cwBjYWxsZWUAY2FsbGVyADxldmFsPgA8cmV0PgA8dmFyPgA8YXJnX3Zhcj4APHdpdGg+AGxhc3RJbmRleAB0YXJnZXQAaW5kZXgAaW5wdXQAZGVmaW5lUHJvcGVydGllcwBhcHBseQBqb2luAGNvbmNhdABzcGxpdABjb25zdHJ1Y3QAZ2V0UHJvdG90eXBlT2YAc2V0UHJvdG90eXBlT2YAaXNFeHRlbnNpYmxlAHByZXZlbnRFeHRlbnNpb25zAGhhcwBkZWxldGVQcm9wZXJ0eQBkZWZpbmVQcm9wZXJ0eQBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IAb3duS2V5cwBhZGQAZG9uZQBuZXh0AHZhbHVlcwBzb3VyY2UAZmxhZ3MAZ2xvYmFsAHVuaWNvZGUAcmF3AG5ldy50YXJnZXQAdGhpcy5hY3RpdmVfZnVuYwA8aG9tZV9vYmplY3Q+ADxjb21wdXRlZF9maWVsZD4APHN0YXRpY19jb21wdXRlZF9maWVsZD4APGNsYXNzX2ZpZWxkc19pbml0PgA8YnJhbmQ+ACNjb25zdHJ1Y3RvcgBhcwBmcm9tAG1ldGEAKmRlZmF1bHQqACoATW9kdWxlAHRoZW4AcmVzb2x2ZQByZWplY3QAcHJvbWlzZQBwcm94eQByZXZva2UAYXN5bmMAZXhlYwBncm91cHMAaW5kaWNlcwBzdGF0dXMAcmVhc29uAGdsb2JhbFRoaXMAYmlnaW50AG5vdC1lcXVhbAB0aW1lZC1vdXQAb2sAdG9KU09OAE9iamVjdABBcnJheQBFcnJvcgBOdW1iZXIAU3RyaW5nAEJvb2xlYW4AU3ltYm9sAEFyZ3VtZW50cwBNYXRoAEpTT04ARGF0ZQBGdW5jdGlvbgBHZW5lcmF0b3JGdW5jdGlvbgBGb3JJbkl0ZXJhdG9yAFJlZ0V4cABBcnJheUJ1ZmZlcgBTaGFyZWRBcnJheUJ1ZmZlcgBVaW50OENsYW1wZWRBcnJheQBJbnQ4QXJyYXkAVWludDhBcnJheQBJbnQxNkFycmF5AFVpbnQxNkFycmF5AEludDMyQXJyYXkAVWludDMyQXJyYXkAQmlnSW50NjRBcnJheQBCaWdVaW50NjRBcnJheQBGbG9hdDMyQXJyYXkARmxvYXQ2NEFycmF5AERhdGFWaWV3AEJpZ0ludABNYXAAU2V0AFdlYWtNYXAAV2Vha1NldABNYXAgSXRlcmF0b3IAU2V0IEl0ZXJhdG9yAEFycmF5IEl0ZXJhdG9yAFN0cmluZyBJdGVyYXRvcgBSZWdFeHAgU3RyaW5nIEl0ZXJhdG9yAEdlbmVyYXRvcgBQcm94eQBQcm9taXNlAFByb21pc2VSZXNvbHZlRnVuY3Rpb24AUHJvbWlzZVJlamVjdEZ1bmN0aW9uAEFzeW5jRnVuY3Rpb24AQXN5bmNGdW5jdGlvblJlc29sdmUAQXN5bmNGdW5jdGlvblJlamVjdABBc3luY0dlbmVyYXRvckZ1bmN0aW9uAEFzeW5jR2VuZXJhdG9yAEV2YWxFcnJvcgBSYW5nZUVycm9yAFJlZmVyZW5jZUVycm9yAFN5bnRheEVycm9yAFR5cGVFcnJvcgBVUklFcnJvcgBJbnRlcm5hbEVycm9yADxicmFuZD4AU3ltYm9sLnRvUHJpbWl0aXZlAFN5bWJvbC5pdGVyYXRvcgBTeW1ib2wubWF0Y2gAU3ltYm9sLm1hdGNoQWxsAFN5bWJvbC5yZXBsYWNlAFN5bWJvbC5zZWFyY2gAU3ltYm9sLnNwbGl0AFN5bWJvbC50b1N0cmluZ1RhZwBTeW1ib2wuaXNDb25jYXRTcHJlYWRhYmxlAFN5bWJvbC5oYXNJbnN0YW5jZQBTeW1ib2wuc3BlY2llcwBTeW1ib2wudW5zY29wYWJsZXMAU3ltYm9sLmFzeW5jSXRlcmF0b3IAAAAAAAEAAAAFAAEUBQABFQUAARUFAAEXBQABFwEAAQABAAEAAQABAAEAAQABAAEAAQABAAIAAQUDAAEKAQEAAAECAQABAwIAAQECAAECAwABAgQAAQMGAAECAwABAwQAAQQFAAEDAwABBAQAAQUFAAECAgABBAQAAQMDAAEDAwABBAQAAQUFAAMCAQ0DAQENAwEADQMCAQ0DAgANAwABDQMDAQoBAQAAAQAAAAEBAgABAAAAAQICAAECAAABAQAAAQEAAAYAABgFAQEPAwIBCgECAQABAQEAAQEBAAUAARcFAAEXBQABFwUBABcFAQAXBQIAFwECAwABAwAABgAAGAYAABgGAQAYBQEBFwUBAhcFAgAXAQIBAAEDAAABAwEAAQIBAAECAgABAwAAAQMBAAEEAAAFAgEXBQEBFwECAgABAgEAAQICAAEDAgABAwIAAgMDBQYCARgCAwEFBgICGAYDAxgDAAEQAwEAEAMBARAD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BOOAQJ+GiIlBY4C8jUHxjUPVhuw0iVKViWwFBUDvAEGAowILhBP6BgBwCQDwCkBXDADwDWDHDyDqF0AFGwBBIAAMqIA3qiBQ/iA6DSF0EQFaFCFEGYFaHaH1aiFF0kGv4iHwAQ4AQWRsYW0sQWRsbQBBaG9tLEFob20AQW5hdG9saWFuX0hpZXJvZ2x5cGhzLEhsdXcAQXJhYmljLEFyYWIAQXJtZW5pYW4sQXJtbgBBdmVzdGFuLEF2c3QAQmFsaW5lc2UsQmFsaQBCYW11bSxCYW11AEJhc3NhX1ZhaCxCYXNzAEJhdGFrLEJhdGsAQmVuZ2FsaSxCZW5nAEJoYWlrc3VraSxCaGtzAEJvcG9tb2ZvLEJvcG8AQnJhaG1pLEJyYWgAQnJhaWxsZSxCcmFpAEJ1Z2luZXNlLEJ1Z2kAQnVoaWQsQnVoZABDYW5hZGlhbl9BYm9yaWdpbmFsLENhbnMAQ2FyaWFuLENhcmkAQ2F1Y2FzaWFuX0FsYmFuaWFuLEFnaGIAQ2hha21hLENha20AQ2hhbSxDaGFtAENoZXJva2VlLENoZXIAQ2hvcmFzbWlhbixDaHJzAENvbW1vbixaeXl5AENvcHRpYyxDb3B0LFFhYWMAQ3VuZWlmb3JtLFhzdXgAQ3lwcmlvdCxDcHJ0AEN5cmlsbGljLEN5cmwAQ3lwcm9fTWlub2FuLENwbW4ARGVzZXJldCxEc3J0AERldmFuYWdhcmksRGV2YQBEaXZlc19Ba3VydSxEaWFrAERvZ3JhLERvZ3IARHVwbG95YW4sRHVwbABFZ3lwdGlhbl9IaWVyb2dseXBocyxFZ3lwAEVsYmFzYW4sRWxiYQBFbHltYWljLEVseW0ARXRoaW9waWMsRXRoaQBHZW9yZ2lhbixHZW9yAEdsYWdvbGl0aWMsR2xhZwBHb3RoaWMsR290aABHcmFudGhhLEdyYW4AR3JlZWssR3JlawBHdWphcmF0aSxHdWpyAEd1bmphbGFfR29uZGksR29uZwBHdXJtdWtoaSxHdXJ1AEhhbixIYW5pAEhhbmd1bCxIYW5nAEhhbmlmaV9Sb2hpbmd5YSxSb2hnAEhhbnVub28sSGFubwBIYXRyYW4sSGF0cgBIZWJyZXcsSGVicgBIaXJhZ2FuYSxIaXJhAEltcGVyaWFsX0FyYW1haWMsQXJtaQBJbmhlcml0ZWQsWmluaCxRYWFpAEluc2NyaXB0aW9uYWxfUGFobGF2aSxQaGxpAEluc2NyaXB0aW9uYWxfUGFydGhpYW4sUHJ0aQBKYXZhbmVzZSxKYXZhAEthaXRoaSxLdGhpAEthbm5hZGEsS25kYQBLYXRha2FuYSxLYW5hAEthd2ksS2F3aQBLYXlhaF9MaSxLYWxpAEtoYXJvc2h0aGksS2hhcgBLaG1lcixLaG1yAEtob2praSxLaG9qAEtoaXRhbl9TbWFsbF9TY3JpcHQsS2l0cwBLaHVkYXdhZGksU2luZABMYW8sTGFvbwBMYXRpbixMYXRuAExlcGNoYSxMZXBjAExpbWJ1LExpbWIATGluZWFyX0EsTGluYQBMaW5lYXJfQixMaW5iAExpc3UsTGlzdQBMeWNpYW4sTHljaQBMeWRpYW4sTHlkaQBNYWthc2FyLE1ha2EATWFoYWphbmksTWFoagBNYWxheWFsYW0sTWx5bQBNYW5kYWljLE1hbmQATWFuaWNoYWVhbixNYW5pAE1hcmNoZW4sTWFyYwBNYXNhcmFtX0dvbmRpLEdvbm0ATWVkZWZhaWRyaW4sTWVkZgBNZWV0ZWlfTWF5ZWssTXRlaQBNZW5kZV9LaWtha3VpLE1lbmQATWVyb2l0aWNfQ3Vyc2l2ZSxNZXJjAE1lcm9pdGljX0hpZXJvZ2x5cGhzLE1lcm8ATWlhbyxQbHJkAE1vZGksTW9kaQBNb25nb2xpYW4sTW9uZwBNcm8sTXJvbwBNdWx0YW5pLE11bHQATXlhbm1hcixNeW1yAE5hYmF0YWVhbixOYmF0AE5hZ19NdW5kYXJpLE5hZ20ATmFuZGluYWdhcmksTmFuZABOZXdfVGFpX0x1ZSxUYWx1AE5ld2EsTmV3YQBOa28sTmtvbwBOdXNodSxOc2h1AE55aWFrZW5nX1B1YWNodWVfSG1vbmcsSG1ucABPZ2hhbSxPZ2FtAE9sX0NoaWtpLE9sY2sAT2xkX0h1bmdhcmlhbixIdW5nAE9sZF9JdGFsaWMsSXRhbABPbGRfTm9ydGhfQXJhYmlhbixOYXJiAE9sZF9QZXJtaWMsUGVybQBPbGRfUGVyc2lhbixYcGVvAE9sZF9Tb2dkaWFuLFNvZ28AT2xkX1NvdXRoX0FyYWJpYW4sU2FyYgBPbGRfVHVya2ljLE9ya2gAT2xkX1V5Z2h1cixPdWdyAE9yaXlhLE9yeWEAT3NhZ2UsT3NnZQBPc21hbnlhLE9zbWEAUGFoYXdoX0htb25nLEhtbmcAUGFsbXlyZW5lLFBhbG0AUGF1X0Npbl9IYXUsUGF1YwBQaGFnc19QYSxQaGFnAFBob2VuaWNpYW4sUGhueABQc2FsdGVyX1BhaGxhdmksUGhscABSZWphbmcsUmpuZwBSdW5pYyxSdW5yAFNhbWFyaXRhbixTYW1yAFNhdXJhc2h0cmEsU2F1cgBTaGFyYWRhLFNocmQAU2hhdmlhbixTaGF3AFNpZGRoYW0sU2lkZABTaWduV3JpdGluZyxTZ253AFNpbmhhbGEsU2luaABTb2dkaWFuLFNvZ2QAU29yYV9Tb21wZW5nLFNvcmEAU295b21ibyxTb3lvAFN1bmRhbmVzZSxTdW5kAFN5bG90aV9OYWdyaSxTeWxvAFN5cmlhYyxTeXJjAFRhZ2Fsb2csVGdsZwBUYWdiYW53YSxUYWdiAFRhaV9MZSxUYWxlAFRhaV9UaGFtLExhbmEAVGFpX1ZpZXQsVGF2dABUYWtyaSxUYWtyAFRhbWlsLFRhbWwAVGFuZ3V0LFRhbmcAVGVsdWd1LFRlbHUAVGhhYW5hLFRoYWEAVGhhaSxUaGFpAFRpYmV0YW4sVGlidABUaWZpbmFnaCxUZm5nAFRpcmh1dGEsVGlyaABUYW5nc2EsVG5zYQBUb3RvLFRvdG8AVWdhcml0aWMsVWdhcgBWYWksVmFpaQBWaXRoa3VxaSxWaXRoAFdhbmNobyxXY2hvAFdhcmFuZ19DaXRpLFdhcmEAWWV6aWRpLFllemkAWWksWWlpaQBaYW5hYmF6YXJfU3F1YXJlLFphbmIAQZC2AgvyIMAZmUeFGZlHrhmAR44ZgEeEGZZHgBmeR4AZ4WBHphmER4QZgQ2TGeAPOIMsgBmCLAGDLIAZgCwDgCyAGYAsgBmCLACALACTLAC+LI0ajyzgJB2BOOBIHQClBQGxBQGCBQC2NQeaNQOFNQqEBIAZhQSAGY0EgBmCBIAZnwSAGYkEijiZBIA44AsEgBmhBI2LALuLAYKLrwSxlQ26ZgGCZq1/AY5/AJtSAYBSAIqLBJ4EAIEEBckEgBmcBNAggziOIIEZmSCDCwCHCwGBCwGVCwCGCwCACwKDCwGI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eW1ib2wAU28sT3RoZXJfU3ltYm9sAFBjLENvbm5lY3Rvcl9QdW5jdHVhdGlvbgBQZCxEYXNoX1B1bmN0dWF0aW9uAFBzLE9wZW5fUHVuY3R1YXRpb24AUGUsQ2xvc2VfUHVuY3R1YXRpb24AUGksSW5pdGlhbF9QdW5jdHVhdGlvbgBQZixGaW5hbF9QdW5jdHVhdGlvbgBQbyxPdGhlcl9QdW5jdHVhdGlvbgBacyxTcGFjZV9TZXBhcmF0b3IAWmwsTGluZV9TZXBhcmF0b3IAWnAsUGFyYWdyYXBoX1NlcGFyYXRvcgBDYyxDb250cm9sLGNudHJsAENmLEZvcm1hdABDcyxTdXJyb2dhdGUAQ28sUHJpdmF0ZV9Vc2UATEMsQ2FzZWRfTGV0dGVyAEwsTGV0dGVyAE0sTWFyayxDb21iaW5pbmdfTWFyawBOLE51bWJlcgBTLFN5bWJvbABQLFB1bmN0dWF0aW9uLHB1bmN0AFosU2VwYXJhdG9yAEMsT3RoZXIAQZDXAguwCA4AAAA+AAAAwAEAAAAOAAAA8AAAAAB/AAAAgAMBAAA8QVNDSUlfSGV4X0RpZ2l0LEFIZXgAQmlkaV9Db250cm9sLEJpZGlfQwBEYXNoAERlcHJlY2F0ZWQsRGVwAERpYWNyaXRpYyxEaWEARXh0ZW5kZXIsRXh0AEhleF9EaWdpdCxIZXgASURTX0JpbmFyeV9PcGVyYXRvcixJRFNCAElEU19UcmluYXJ5X09wZXJhdG9yLElEU1QASWRlb2dyYXBoaWMsSWRlbwBKb2luX0NvbnRyb2wsSm9pbl9DAExvZ2ljYWxfT3JkZXJfRXhjZXB0aW9uLExPRQBOb25jaGFyYWN0ZXJfQ29kZV9Qb2ludCxOQ2hhcgBQYXR0ZXJuX1N5bnRheCxQYXRfU3luAFBhdHRlcm5fV2hpdGVfU3BhY2UsUGF0X1dTAFF1b3RhdGlvbl9NYXJrLFFNYXJrAFJhZGljYWwAUmVnaW9uYWxfSW5kaWNhdG9yLFJJAFNlbnRlbmNlX1Rlcm1pbmFsLFNUZXJtAFNvZnRfRG90dGVkLFNEAFRlcm1pbmFsX1B1bmN0dWF0aW9uLFRlcm0AVW5pZmllZF9JZGVvZ3JhcGgsVUlkZW8AVmFyaWF0aW9uX1NlbGVjdG9yLFZTAFdoaXRlX1NwYWNlLHNwYWNlAEJpZGlfTWlycm9yZWQsQmlkaV9NAEVtb2ppAEVtb2ppX0NvbXBvbmVudCxFQ29tcABFbW9qaV9Nb2RpZmllcixFTW9kAEVtb2ppX01vZGlmaWVyX0Jhc2UsRUJhc2UARW1vamlfUHJlc2VudGF0aW9uLEVQcmVzAEV4dGVuZGVkX1BpY3RvZ3JhcGhpYyxFeHRQaWN0AERlZmF1bHRfSWdub3JhYmxlX0NvZGVfUG9pbnQsREkASURfU3RhcnQsSURTAENhc2VfSWdub3JhYmxlLENJAEFTQ0lJAEFscGhhYmV0aWMsQWxwaGEAQW55AEFzc2lnbmVkAENhc2VkAENoYW5nZXNfV2hlbl9DYXNlZm9sZGVkLENXQ0YAQ2hhbmdlc19XaGVuX0Nhc2VtYXBwZWQsQ1dDTQBDaGFuZ2VzX1doZW5fTG93ZXJjYXNlZCxDV0wAQ2hhbmdlc19XaGVuX05GS0NfQ2FzZWZvbGRlZCxDV0tDRgBDaGFuZ2VzX1doZW5fVGl0bGVjYXNlZCxDV1QAQ2hhbmdlc19XaGVuX1VwcGVyY2FzZWQsQ1dVAEdyYXBoZW1lX0Jhc2UsR3JfQmFzZQBHcmFwaGVtZV9FeHRlbmQsR3JfRXh0AElEX0NvbnRpbnVlLElEQwBMb3dlcmNhc2UsTG93ZXIATWF0aABVcHBlcmNhc2UsVXBwZXIAWElEX0NvbnRpbnVlLFhJREMAWElEX1N0YXJ0LFhJRFMAQdDfAgvyAgEAnAYHTQMEEACPCwAAEQAIAFNKUQBSAFMAOlRVAFdZP11cAEZhY0JkAGYAaABqAGwAbgAAQAAAAAAaAJMAACA1ACcAIQAkIioAE2ttACYkJxQWGBscPh4/Hzk9IiFBHkAlJSYoICpILEMuSzBMMkRCmQAAlY99foOEEoCCdncSe6N8eHmKkpimoIUAmqGTdTOVAI4AdJmYl5YAAJ4AnAChoBUuLzC0tU+qqRIUHiEiIio0NaanNh9JAACXAVraHTYFAMTDxsXIx8rJzMvE1UXWQtdG2M7Q0tTa2e72/g4HD4CfACGAo+0AwEDGYOfb5pnAAAAGYNwp/RUSBhb43QYVEoQIxhb/3wPAQABGYN7gbTc4ORUUFxYAGhkcGwBft2VERwBPYk5QAABIAAAAo6SlAAAAAAC2AABaAEcAW1ZY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n4PLdYFAzXWfjM11gcDTdS0D1HWfiNV1gcDZdZ8D2nWBwNt1nwzcdYFA4nUtg+J1nwjkdYFA6HWfg+h1gUDqdZ+M6nWBwPB1LQTxdR+F83UfBfZ1H4X4dR8F+3Ufhf11nwQMeJ9BDnifBQ94A8IReK3QEngDARt4LQKAe61NgXsDQoh7gcCJey1FinsDBI17gYCQewPckXstBaB7rciie4NEqHutyKp7lwBAfCFFQHwlDUR8h4BKfBXBSnwXQUt8Hw1MfBeCUnyZgFN8l8BTfJeBWnyXAGR8LwGAfIGAgHwDFoR8wQSQfAMBlHwfBfx+rAEAvhDRAL6sRwm+EDkNviyHKb4sAi2+kDcuvpD/Sb4QvGm+AAAAACAAAABhAAIABAAGALwDCAAKAAwAFQCVAKUAuQDBAMMAxwDLANEA1wDdAOAA5gD4AAgBCgFzABABEgEUASABLAFEAU0BUwFiAWgBagF2AZIBlAGpAbsBxwHRAdUBuQLXATsA2QHbAbcA4QH8AQwCGAIdAiMCJwKjAzMCPwJCAksCTgJRAl0CYAJpAmwCbwJ1AngCgQKKApwCnwKjAq8CuQLFAskCzQLRAtUC5wLtAvEC9QL5Av0CBQMJAw0DEwMXAxsDIwMnAysDLwM1Az0DQQNJA00DUQMLD1cDWwNfA2MDZwNrA28DcwN5A30DgQOFA4kDjQORA5UDmQOdA6ED3BClA8kDzQPZA90D4QPvA/EDPQRPBJkE8AQCBUoFZAVsBXAFcwWaBfoF/gUHBgsGFAYYBh4GIgYoBo4GlAaYBp4GogarBqwD8watA/YGrgP5Bq8D/AbMA/8GzQMCB84DBQcJBw0HEQeGAzIHNQe5AzcHOweIA1MHiQNWB5ADaweKA3cHsAOJB44DmQefB6MHjAO4B48Duwe0AL4HwAfCBxAgywcuAM0HzwcgANIH1gfbB98H5AfqB/AHIAD2BxIiAQgFCAcIHQglCCcIQwAtCDAIkAE2CDkITgBFCEcITAhOCFEIWgCpA1oAUwhXCGAIaQBiCGUIbwh0CHoIfgiiCEkApAimCKkIVgCrCK0IsAi0CFgAtgi4CLsIwAjCCMUIdgDHCMkIzAjQCHgA0gjUCNcI2wjeCOQI5wjwCPMI9gj5CAIJBgkLCQ8JFAkXCRoJIwksCTsJPglBCUQJRwlKCVYJXAlgCWIJZAloCWoJ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\";if(!K(L)){var M=L;L=d.locateFile?d.locateFile(M,q):q+M;}function ca(){var a=L;return Promise.resolve().then(()=>{if(a==L&&v)var b=new Uint8Array(v);else{if(K(a)){b=atob(a.slice(37));for(var c=new Uint8Array(b.length),e=0;e<b.length;++e)c[e]=b.charCodeAt(e);b=c;}else b=void 0;if(!b)throw\"both async and sync fetching of the wasm failed\";}return b;});}function da(a,b){return ca().then(c=>WebAssembly.instantiate(c,a)).then(c=>c).then(b,c=>{u(`failed to asynchronously prepare wasm: ${c}`);w(c);});}function ea(a,b){return da(a,b);}var N=a=>{for(;0<a.length;)a.shift()(d);},O=\"undefined\"!=typeof TextDecoder?new TextDecoder(\"utf8\"):void 0,P=(a,b)=>{for(var c=b+NaN,e=b;a[e]&&!(e>=c);)++e;if(16<e-b&&a.buffer&&O)return O.decode(a.subarray(b,e));for(c=\"\";b<e;){var f=a[b++];if(f&128){var g=a[b++]&63;if(192==(f&224))c+=String.fromCharCode((f&31)<<6|g);else{var l=a[b++]&63;f=224==(f&240)?(f&15)<<12|g<<6|l:(f&7)<<18|g<<12|l<<6|a[b++]&63;65536>f?c+=String.fromCharCode(f):(f-=65536,c+=String.fromCharCode(55296|f>>10,56320|f&1023));}}else c+=String.fromCharCode(f);}return c;},fa=[0,31,60,91,121,152,182,213,244,274,305,335],ha=[0,31,59,90,120,151,181,212,243,273,304,334],Q=a=>{for(var b=0,c=0;c<a.length;++c){var e=a.charCodeAt(c);127>=e?b++:2047>=e?b+=2:55296<=e&&57343>=e?(b+=4,++c):b+=3;}return b;},R=(a,b,c)=>{var e=A;if(0<c){c=b+c-1;for(var f=0;f<a.length;++f){var g=a.charCodeAt(f);if(55296<=g&&57343>=g){var l=a.charCodeAt(++f);g=65536+((g&1023)<<10)|l&1023;}if(127>=g){if(b>=c)break;e[b++]=g;}else{if(2047>=g){if(b+1>=c)break;e[b++]=192|g>>6;}else{if(65535>=g){if(b+2>=c)break;e[b++]=224|g>>12;}else{if(b+3>=c)break;e[b++]=240|g>>18;e[b++]=128|g>>12&63;}e[b++]=128|g>>6&63;}e[b++]=128|g&63;}}e[b]=0;}},T=a=>{var b=Q(a)+1,c=S(b);c&&R(a,c,b);return c;};function U(){}var ia=[null,[],[]],ka=(a,b,c,e)=>{var f={string:h=>{var r=0;if(null!==h&&void 0!==h&&0!==h){r=Q(h)+1;var Y=V(r);R(h,Y,r);r=Y;}return r;},array:h=>{var r=V(h.length);z.set(h,r);return r;}};a=d[\"_\"+a];var g=[],l=0;if(e)for(var m=0;m<e.length;m++){var t=f[c[m]];t?(0===l&&(l=W()),g[m]=t(e[m])):g[m]=e[m];}c=a.apply(null,g);return c=function(h){0!==l&&ja(l);return\"string\"===b?h?P(A,h):\"\":\"boolean\"===b?!!h:h;}(c);};U=(a,b,c)=>{a=a?P(A,a):\"\";b=null!==b?JSON.parse(b?P(A,b):\"\"):[];try{const e=d.externalCall(a,b);return e?T(e):null;}catch(e){return d.HEAPU8[c]=1,T(e.message);}};var la={a:(a,b,c,e)=>{w(`Assertion failed: ${a?P(A,a):\"\"}, at: `+[b?b?P(A,b):\"\":\"unknown filename\",c,e?e?P(A,e):\"\":\"unknown function\"]);},i:function(a,b,c){a=new Date(1E3*(b+2097152>>>0<4194305-!!a?(a>>>0)+4294967296*b:NaN));B[c>>2]=a.getSeconds();B[c+4>>2]=a.getMinutes();B[c+8>>2]=a.getHours();B[c+12>>2]=a.getDate();B[c+16>>2]=a.getMonth();B[c+20>>2]=a.getFullYear()-1900;B[c+24>>2]=a.getDay();b=a.getFullYear();B[c+28>>2]=(0!==b%4||0===b%100&&0!==b%400?ha:fa)[a.getMonth()]+a.getDate()-1|0;B[c+36>>2]=-(60*a.getTimezoneOffset());b=new Date(a.getFullYear(),6,1).getTimezoneOffset();var e=new Date(a.getFullYear(),0,1).getTimezoneOffset();B[c+32>>2]=(b!=e&&a.getTimezoneOffset()==Math.min(e,b))|0;},d:(a,b,c)=>{function e(t){return(t=t.toTimeString().match(/\\(([A-Za-z ]+)\\)$/))?t[1]:\"GMT\";}var f=new Date().getFullYear(),g=new Date(f,0,1),l=new Date(f,6,1);f=g.getTimezoneOffset();var m=l.getTimezoneOffset();C[a>>2]=60*Math.max(f,m);B[b>>2]=Number(f!=m);a=e(g);b=e(l);a=T(a);b=T(b);m<f?(C[c>>2]=a,C[c+4>>2]=b):(C[c>>2]=b,C[c+4>>2]=a);},b:()=>{w(\"\");},g:U,f:function(a,b){a=a?P(A,a):\"\";let c;try{c=window.JSON.parse(a);}catch(e){c=a;}0!==b?window.alert(a):window.console.error(\"DUMP\",c);},e:()=>Date.now(),j:a=>{var b=A.length;a>>>=0;if(2147483648<a)return!1;for(var c=1;4>=c;c*=2){var e=b*(1+.2/c);e=Math.min(e,a+100663296);var f=Math;e=Math.max(a,e);a:{f=(f.min.call(f,2147483648,e+(65536-e%65536)%65536)-x.buffer.byteLength+65535)/65536;try{x.grow(f);D();var g=1;break a;}catch(l){}g=void 0;}if(g)return!0;}return!1;},c:(a,b,c,e)=>{for(var f=0,g=0;g<c;g++){var l=C[b>>2],m=C[b+4>>2];b+=8;for(var t=0;t<m;t++){var h=A[l+t],r=ia[a];0===h||10===h?((1===a?aa:u)(P(r,0)),r.length=0):r.push(h);}f+=m;}C[e>>2]=f;return 0;},k:function(a){a=a?P(A,a):\"\";window.console.error(a);},h:function(a){a=a?P(A,a):\"\";return Date.parse(a);},l:function(a,b,c,e){a=a?P(A,a):\"\";b=b?P(A,b):\"\";c=c?P(A,c):\"\";c=`Quickjs -- ${a}: ${b}\\n${c}`;0!==e?window.alert(c):window.console.error(c);}},X=function(){function a(c){X=c.exports;x=X.m;D();F.unshift(X.n);H--;d.monitorRunDependencies?.(H);0==H&&(null!==I&&(clearInterval(I),I=null),J&&(c=J,J=null,c()));return X;}var b={a:la};H++;d.monitorRunDependencies?.(H);if(d.instantiateWasm)try{return d.instantiateWasm(b,a);}catch(c){u(`Module.instantiateWasm callback failed with error: ${c}`),n(c);}ea(b,function(c){a(c.instance);}).catch(n);return{};}();d._evalInSandbox=(a,b)=>(d._evalInSandbox=X.o)(a,b);d._nukeSandbox=()=>(d._nukeSandbox=X.p)();d._init=(a,b)=>(d._init=X.q)(a,b);d._commFun=(a,b)=>(d._commFun=X.r)(a,b);d._dumpMemoryUse=()=>(d._dumpMemoryUse=X.s)();var S=a=>(S=X.t)(a);d._free=a=>(d._free=X.u)(a);var W=()=>(W=X.w)(),ja=a=>(ja=X.x)(a),V=a=>(V=X.y)(a);d.ccall=ka;d.cwrap=(a,b,c,e)=>{var f=!c||c.every(g=>\"number\"===g||\"boolean\"===g);return\"string\"!==b&&f&&!e?d[\"_\"+a]:function(){return ka(a,b,c,arguments,e);};};d.stringToNewUTF8=T;var Z;J=function ma(){Z||na();Z||(J=ma);};function na(){function a(){if(!Z&&(Z=!0,d.calledRun=!0,!y)){N(F);k(d);if(d.onRuntimeInitialized)d.onRuntimeInitialized();if(d.postRun)for(\"function\"==typeof d.postRun&&(d.postRun=[d.postRun]);d.postRun.length;){var b=d.postRun.shift();G.unshift(b);}N(G);}}if(!(0<H)){if(d.preRun)for(\"function\"==typeof d.preRun&&(d.preRun=[d.preRun]);d.preRun.length;)ba();N(E);0<H||(d.setStatus?(d.setStatus(\"Running...\"),setTimeout(function(){setTimeout(function(){d.setStatus(\"\");},1);a();},1)):a());}}if(d.preInit)for(\"function\"==typeof d.preInit&&(d.preInit=[d.preInit]);0<d.preInit.length;)d.preInit.pop()();na();return moduleArg.ready;};})();/* harmony default export */ const quickjs_eval = (Module);\n;// ./src/pdf.sandbox.external.js\nclass SandboxSupportBase {\n  constructor(win) {\n    this.win = win;\n    this.timeoutIds = new Map();\n    this.commFun = null;\n  }\n  destroy() {\n    this.commFun = null;\n    for (const id of this.timeoutIds.values()) {\n      this.win.clearTimeout(id);\n    }\n    this.timeoutIds = null;\n  }\n  exportValueToSandbox(val) {\n    throw new Error(\"Not implemented\");\n  }\n  importValueFromSandbox(val) {\n    throw new Error(\"Not implemented\");\n  }\n  createErrorForSandbox(errorMessage) {\n    throw new Error(\"Not implemented\");\n  }\n  callSandboxFunction(name, args) {\n    try {\n      args = this.exportValueToSandbox(args);\n      this.commFun(name, args);\n    } catch (e) {\n      this.win.console.error(e);\n    }\n  }\n  createSandboxExternals() {\n    const externals = {\n      setTimeout: (callbackId, nMilliseconds) => {\n        if (typeof callbackId !== \"number\" || typeof nMilliseconds !== \"number\") {\n          return;\n        }\n        if (callbackId === 0) {\n          this.win.clearTimeout(this.timeoutIds.get(callbackId));\n        }\n        const id = this.win.setTimeout(() => {\n          this.timeoutIds.delete(callbackId);\n          this.callSandboxFunction(\"timeoutCb\", {\n            callbackId,\n            interval: false\n          });\n        }, nMilliseconds);\n        this.timeoutIds.set(callbackId, id);\n      },\n      clearTimeout: callbackId => {\n        this.win.clearTimeout(this.timeoutIds.get(callbackId));\n        this.timeoutIds.delete(callbackId);\n      },\n      setInterval: (callbackId, nMilliseconds) => {\n        if (typeof callbackId !== \"number\" || typeof nMilliseconds !== \"number\") {\n          return;\n        }\n        const id = this.win.setInterval(() => {\n          this.callSandboxFunction(\"timeoutCb\", {\n            callbackId,\n            interval: true\n          });\n        }, nMilliseconds);\n        this.timeoutIds.set(callbackId, id);\n      },\n      clearInterval: callbackId => {\n        this.win.clearInterval(this.timeoutIds.get(callbackId));\n        this.timeoutIds.delete(callbackId);\n      },\n      alert: cMsg => {\n        if (typeof cMsg !== \"string\") {\n          return;\n        }\n        this.win.alert(cMsg);\n      },\n      confirm: cMsg => {\n        if (typeof cMsg !== \"string\") {\n          return false;\n        }\n        return this.win.confirm(cMsg);\n      },\n      prompt: (cQuestion, cDefault) => {\n        if (typeof cQuestion !== \"string\" || typeof cDefault !== \"string\") {\n          return null;\n        }\n        return this.win.prompt(cQuestion, cDefault);\n      },\n      parseURL: cUrl => {\n        const url = new this.win.URL(cUrl);\n        const props = [\"hash\", \"host\", \"hostname\", \"href\", \"origin\", \"password\", \"pathname\", \"port\", \"protocol\", \"search\", \"searchParams\", \"username\"];\n        return Object.fromEntries(props.map(name => [name, url[name].toString()]));\n      },\n      send: data => {\n        if (!data) {\n          return;\n        }\n        const event = new this.win.CustomEvent(\"updatefromsandbox\", {\n          detail: this.importValueFromSandbox(data)\n        });\n        this.win.dispatchEvent(event);\n      }\n    };\n    Object.setPrototypeOf(externals, null);\n    return (name, args) => {\n      try {\n        const result = externals[name](...args);\n        return this.exportValueToSandbox(result);\n      } catch (error) {\n        throw this.createErrorForSandbox(error?.toString() ?? \"\");\n      }\n    };\n  }\n}\n;// ./src/pdf.sandbox.js\n\n\nconst pdfjsVersion = \"4.1.0\";\nconst pdfjsBuild = \"849f8548b1\";\nclass SandboxSupport extends SandboxSupportBase {\n  exportValueToSandbox(val) {\n    return JSON.stringify(val);\n  }\n  importValueFromSandbox(val) {\n    return val;\n  }\n  createErrorForSandbox(errorMessage) {\n    return new Error(errorMessage);\n  }\n}\nclass Sandbox {\n  constructor(win, module) {\n    this.support = new SandboxSupport(win, this);\n    module.externalCall = this.support.createSandboxExternals();\n    this._module = module;\n    this._alertOnError = 0;\n  }\n  create(data) {\n    const code = [\"\\n;// ./src/scripting_api/constants.js\\nconst Border = Object.freeze({\\n  s: \\\"solid\\\",\\n  d: \\\"dashed\\\",\\n  b: \\\"beveled\\\",\\n  i: \\\"inset\\\",\\n  u: \\\"underline\\\"\\n});\\nconst Cursor = Object.freeze({\\n  visible: 0,\\n  hidden: 1,\\n  delay: 2\\n});\\nconst Display = Object.freeze({\\n  visible: 0,\\n  hidden: 1,\\n  noPrint: 2,\\n  noView: 3\\n});\\nconst Font = Object.freeze({\\n  Times: \\\"Times-Roman\\\",\\n  TimesB: \\\"Times-Bold\\\",\\n  TimesI: \\\"Times-Italic\\\",\\n  TimesBI: \\\"Times-BoldItalic\\\",\\n  Helv: \\\"Helvetica\\\",\\n  HelvB: \\\"Helvetica-Bold\\\",\\n  HelvI: \\\"Helvetica-Oblique\\\",\\n  HelvBI: \\\"Helvetica-BoldOblique\\\",\\n  Cour: \\\"Courier\\\",\\n  CourB: \\\"Courier-Bold\\\",\\n  CourI: \\\"Courier-Oblique\\\",\\n  CourBI: \\\"Courier-BoldOblique\\\",\\n  Symbol: \\\"Symbol\\\",\\n  ZapfD: \\\"ZapfDingbats\\\",\\n  KaGo: \\\"HeiseiKakuGo-W5-UniJIS-UCS2-H\\\",\\n  KaMi: \\\"HeiseiMin-W3-UniJIS-UCS2-H\\\"\\n});\\nconst Highlight = Object.freeze({\\n  n: \\\"none\\\",\\n  i: \\\"invert\\\",\\n  p: \\\"push\\\",\\n  o: \\\"outline\\\"\\n});\\nconst Position = Object.freeze({\\n  textOnly: 0,\\n  iconOnly: 1,\\n  iconTextV: 2,\\n  textIconV: 3,\\n  iconTextH: 4,\\n  textIconH: 5,\\n  overlay: 6\\n});\\nconst ScaleHow = Object.freeze({\\n  proportional: 0,\\n  anamorphic: 1\\n});\\nconst ScaleWhen = Object.freeze({\\n  always: 0,\\n  never: 1,\\n  tooBig: 2,\\n  tooSmall: 3\\n});\\nconst Style = Object.freeze({\\n  ch: \\\"check\\\",\\n  cr: \\\"cross\\\",\\n  di: \\\"diamond\\\",\\n  ci: \\\"circle\\\",\\n  st: \\\"star\\\",\\n  sq: \\\"square\\\"\\n});\\nconst Trans = Object.freeze({\\n  blindsH: \\\"BlindsHorizontal\\\",\\n  blindsV: \\\"BlindsVertical\\\",\\n  boxI: \\\"BoxIn\\\",\\n  boxO: \\\"BoxOut\\\",\\n  dissolve: \\\"Dissolve\\\",\\n  glitterD: \\\"GlitterDown\\\",\\n  glitterR: \\\"GlitterRight\\\",\\n  glitterRD: \\\"GlitterRightDown\\\",\\n  random: \\\"Random\\\",\\n  replace: \\\"Replace\\\",\\n  splitHI: \\\"SplitHorizontalIn\\\",\\n  splitHO: \\\"SplitHorizontalOut\\\",\\n  splitVI: \\\"SplitVerticalIn\\\",\\n  splitVO: \\\"SplitVerticalOut\\\",\\n  wipeD: \\\"WipeDown\\\",\\n  wipeL: \\\"WipeLeft\\\",\\n  wipeR: \\\"WipeRight\\\",\\n  wipeU: \\\"WipeUp\\\"\\n});\\nconst ZoomType = Object.freeze({\\n  none: \\\"NoVary\\\",\\n  fitP: \\\"FitPage\\\",\\n  fitW: \\\"FitWidth\\\",\\n  fitH: \\\"FitHeight\\\",\\n  fitV: \\\"FitVisibleWidth\\\",\\n  pref: \\\"Preferred\\\",\\n  refW: \\\"ReflowWidth\\\"\\n});\\nconst GlobalConstants = Object.freeze({\\n  IDS_GREATER_THAN: \\\"Invalid value: must be greater than or equal to % s.\\\",\\n  IDS_GT_AND_LT: \\\"Invalid value: must be greater than or equal to % s \\\" + \\\"and less than or equal to % s.\\\",\\n  IDS_LESS_THAN: \\\"Invalid value: must be less than or equal to % s.\\\",\\n  IDS_INVALID_MONTH: \\\"** Invalid **\\\",\\n  IDS_INVALID_DATE: \\\"Invalid date / time: please ensure that the date / time exists. Field\\\",\\n  IDS_INVALID_DATE2: \\\" should match format \\\",\\n  IDS_INVALID_VALUE: \\\"The value entered does not match the format of the field\\\",\\n  IDS_AM: \\\"am\\\",\\n  IDS_PM: \\\"pm\\\",\\n  IDS_MONTH_INFO: \\\"January[1] February[2] March[3] April[4] May[5] \\\" + \\\"June[6] July[7] August[8] September[9] October[10] \\\" + \\\"November[11] December[12] Sept[9] Jan[1] Feb[2] Mar[3] \\\" + \\\"Apr[4] Jun[6] Jul[7] Aug[8] Sep[9] Oct[10] Nov[11] Dec[12]\\\",\\n  IDS_STARTUP_CONSOLE_MSG: \\\"** ^ _ ^ **\\\",\\n  RE_NUMBER_ENTRY_DOT_SEP: [\\\"[+-]?\\\\\\\\d*\\\\\\\\.?\\\\\\\\d*\\\"],\\n  RE_NUMBER_COMMIT_DOT_SEP: [\\\"[+-]?\\\\\\\\d+(\\\\\\\\.\\\\\\\\d+)?\\\", \\\"[+-]?\\\\\\\\.\\\\\\\\d+\\\", \\\"[+-]?\\\\\\\\d+\\\\\\\\.\\\"],\\n  RE_NUMBER_ENTRY_COMMA_SEP: [\\\"[+-]?\\\\\\\\d*,?\\\\\\\\d*\\\"],\\n  RE_NUMBER_COMMIT_COMMA_SEP: [\\\"[+-]?\\\\\\\\d+([.,]\\\\\\\\d+)?\\\", \\\"[+-]?[.,]\\\\\\\\d+\\\", \\\"[+-]?\\\\\\\\d+[.,]\\\"],\\n  RE_ZIP_ENTRY: [\\\"\\\\\\\\d{0,5}\\\"],\\n  RE_ZIP_COMMIT: [\\\"\\\\\\\\d{5}\\\"],\\n  RE_ZIP4_ENTRY: [\\\"\\\\\\\\d{0,5}(\\\\\\\\.|[- ])?\\\\\\\\d{0,4}\\\"],\\n  RE_ZIP4_COMMIT: [\\\"\\\\\\\\d{5}(\\\\\\\\.|[- ])?\\\\\\\\d{4}\\\"],\\n  RE_PHONE_ENTRY: [\\\"\\\\\\\\d{0,3}(\\\\\\\\.|[- ])?\\\\\\\\d{0,3}(\\\\\\\\.|[- ])?\\\\\\\\d{0,4}\\\", \\\"\\\\\\\\(\\\\\\\\d{0,3}\\\", \\\"\\\\\\\\(\\\\\\\\d{0,3}\\\\\\\\)(\\\\\\\\.|[- ])?\\\\\\\\d{0,3}(\\\\\\\\.|[- ])?\\\\\\\\d{0,4}\\\", \\\"\\\\\\\\(\\\\\\\\d{0,3}(\\\\\\\\.|[- ])?\\\\\\\\d{0,3}(\\\\\\\\.|[- ])?\\\\\\\\d{0,4}\\\", \\\"\\\\\\\\d{0,3}\\\\\\\\)(\\\\\\\\.|[- ])?\\\\\\\\d{0,3}(\\\\\\\\.|[- ])?\\\\\\\\d{0,4}\\\", \\\"011(\\\\\\\\.|[- \\\\\\\\d])*\\\"],\\n  RE_PHONE_COMMIT: [\\\"\\\\\\\\d{3}(\\\\\\\\.|[- ])?\\\\\\\\d{4}\\\", \\\"\\\\\\\\d{3}(\\\\\\\\.|[- ])?\\\\\\\\d{3}(\\\\\\\\.|[- ])?\\\\\\\\d{4}\\\", \\\"\\\\\\\\(\\\\\\\\d{3}\\\\\\\\)(\\\\\\\\.|[- ])?\\\\\\\\d{3}(\\\\\\\\.|[- ])?\\\\\\\\d{4}\\\", \\\"011(\\\\\\\\.|[- \\\\\\\\d])*\\\"],\\n  RE_SSN_ENTRY: [\\\"\\\\\\\\d{0,3}(\\\\\\\\.|[- ])?\\\\\\\\d{0,2}(\\\\\\\\.|[- ])?\\\\\\\\d{0,4}\\\"],\\n  RE_SSN_COMMIT: [\\\"\\\\\\\\d{3}(\\\\\\\\.|[- ])?\\\\\\\\d{2}(\\\\\\\\.|[- ])?\\\\\\\\d{4}\\\"]\\n});\\n\\n;// ./src/scripting_api/common.js\\nconst FieldType = {\\n  none: 0,\\n  number: 1,\\n  percent: 2,\\n  date: 3,\\n  time: 4\\n};\\nfunction createActionsMap(actions) {\\n  const actionsMap = new Map();\\n  if (actions) {\\n    for (const [eventType, actionsForEvent] of Object.entries(actions)) {\\n      actionsMap.set(eventType, actionsForEvent);\\n    }\\n  }\\n  return actionsMap;\\n}\\nfunction getFieldType(actions) {\\n  let format = actions.get(\\\"Format\\\");\\n  if (!format) {\\n    return FieldType.none;\\n  }\\n  format = format[0];\\n  format = format.trim();\\n  if (format.startsWith(\\\"AFNumber_\\\")) {\\n    return FieldType.number;\\n  }\\n  if (format.startsWith(\\\"AFPercent_\\\")) {\\n    return FieldType.percent;\\n  }\\n  if (format.startsWith(\\\"AFDate_\\\")) {\\n    return FieldType.date;\\n  }\\n  if (format.startsWith(\\\"AFTime_\\\")) {\\n    return FieldType.time;\\n  }\\n  return FieldType.none;\\n}\\n\\n;// ./src/shared/scripting_utils.js\\nfunction makeColorComp(n) {\\n  return Math.floor(Math.max(0, Math.min(1, n)) * 255).toString(16).padStart(2, \\\"0\\\");\\n}\\nfunction scaleAndClamp(x) {\\n  return Math.max(0, Math.min(255, 255 * x));\\n}\\nclass ColorConverters {\\n  static CMYK_G([c, y, m, k]) {\\n    return [\\\"G\\\", 1 - Math.min(1, 0.3 * c + 0.59 * m + 0.11 * y + k)];\\n  }\\n  static G_CMYK([g]) {\\n    return [\\\"CMYK\\\", 0, 0, 0, 1 - g];\\n  }\\n  static G_RGB([g]) {\\n    return [\\\"RGB\\\", g, g, g];\\n  }\\n  static G_rgb([g]) {\\n    g = scaleAndClamp(g);\\n    return [g, g, g];\\n  }\\n  static G_HTML([g]) {\\n    const G = makeColorComp(g);\\n    return `#${G}${G}${G}`;\\n  }\\n  static RGB_G([r, g, b]) {\\n    return [\\\"G\\\", 0.3 * r + 0.59 * g + 0.11 * b];\\n  }\\n  static RGB_rgb(color) {\\n    return color.map(scaleAndClamp);\\n  }\\n  static RGB_HTML(color) {\\n    return `#${color.map(makeColorComp).join(\\\"\\\")}`;\\n  }\\n  static T_HTML() {\\n    return \\\"#00000000\\\";\\n  }\\n  static T_rgb() {\\n    return [null];\\n  }\\n  static CMYK_RGB([c, y, m, k]) {\\n    return [\\\"RGB\\\", 1 - Math.min(1, c + k), 1 - Math.min(1, m + k), 1 - Math.min(1, y + k)];\\n  }\\n  static CMYK_rgb([c, y, m, k]) {\\n    return [scaleAndClamp(1 - Math.min(1, c + k)), scaleAndClamp(1 - Math.min(1, m + k)), scaleAndClamp(1 - Math.min(1, y + k))];\\n  }\\n  static CMYK_HTML(components) {\\n    const rgb = this.CMYK_RGB(components).slice(1);\\n    return this.RGB_HTML(rgb);\\n  }\\n  static RGB_CMYK([r, g, b]) {\\n    const c = 1 - r;\\n    const m = 1 - g;\\n    const y = 1 - b;\\n    const k = Math.min(c, m, y);\\n    return [\\\"CMYK\\\", c, m, y, k];\\n  }\\n}\\n\\n;// ./src/scripting_api/pdf_object.js\\nclass PDFObject {\\n  constructor(data) {\\n    this._expandos = Object.create(null);\\n    this._send = data.send || null;\\n    this._id = data.id || null;\\n  }\\n}\\n\\n;// ./src/scripting_api/color.js\\n\\n\\nclass Color extends PDFObject {\\n  constructor() {\\n    super({});\\n    this.transparent = [\\\"T\\\"];\\n    this.black = [\\\"G\\\", 0];\\n    this.white = [\\\"G\\\", 1];\\n    this.red = [\\\"RGB\\\", 1, 0, 0];\\n    this.green = [\\\"RGB\\\", 0, 1, 0];\\n    this.blue = [\\\"RGB\\\", 0, 0, 1];\\n    this.cyan = [\\\"CMYK\\\", 1, 0, 0, 0];\\n    this.magenta = [\\\"CMYK\\\", 0, 1, 0, 0];\\n    this.yellow = [\\\"CMYK\\\", 0, 0, 1, 0];\\n    this.dkGray = [\\\"G\\\", 0.25];\\n    this.gray = [\\\"G\\\", 0.5];\\n    this.ltGray = [\\\"G\\\", 0.75];\\n  }\\n  static _isValidSpace(cColorSpace) {\\n    return typeof cColorSpace === \\\"string\\\" && (cColorSpace === \\\"T\\\" || cColorSpace === \\\"G\\\" || cColorSpace === \\\"RGB\\\" || cColorSpace === \\\"CMYK\\\");\\n  }\\n  static _isValidColor(colorArray) {\\n    if (!Array.isArray(colorArray) || colorArray.length === 0) {\\n      return false;\\n    }\\n    const space = colorArray[0];\\n    if (!Color._isValidSpace(space)) {\\n      return false;\\n    }\\n    switch (space) {\\n      case \\\"T\\\":\\n        if (colorArray.length !== 1) {\\n          return false;\\n        }\\n        break;\\n      case \\\"G\\\":\\n        if (colorArray.length !== 2) {\\n          return false;\\n        }\\n        break;\\n      case \\\"RGB\\\":\\n        if (colorArray.length !== 4) {\\n          return false;\\n        }\\n        break;\\n      case \\\"CMYK\\\":\\n        if (colorArray.length !== 5) {\\n          return false;\\n        }\\n        break;\\n      default:\\n        return false;\\n    }\\n    return colorArray.slice(1).every(c => typeof c === \\\"number\\\" && c >= 0 && c <= 1);\\n  }\\n  static _getCorrectColor(colorArray) {\\n    return Color._isValidColor(colorArray) ? colorArray : [\\\"G\\\", 0];\\n  }\\n  convert(colorArray, cColorSpace) {\\n    if (!Color._isValidSpace(cColorSpace)) {\\n      return this.black;\\n    }\\n    if (cColorSpace === \\\"T\\\") {\\n      return [\\\"T\\\"];\\n    }\\n    colorArray = Color._getCorrectColor(colorArray);\\n    if (colorArray[0] === cColorSpace) {\\n      return colorArray;\\n    }\\n    if (colorArray[0] === \\\"T\\\") {\\n      return this.convert(this.black, cColorSpace);\\n    }\\n    return ColorConverters[`${colorArray[0]}_${cColorSpace}`](colorArray.slice(1));\\n  }\\n  equal(colorArray1, colorArray2) {\\n    colorArray1 = Color._getCorrectColor(colorArray1);\\n    colorArray2 = Color._getCorrectColor(colorArray2);\\n    if (colorArray1[0] === \\\"T\\\" || colorArray2[0] === \\\"T\\\") {\\n      return colorArray1[0] === \\\"T\\\" && colorArray2[0] === \\\"T\\\";\\n    }\\n    if (colorArray1[0] !== colorArray2[0]) {\\n      colorArray2 = this.convert(colorArray2, colorArray1[0]);\\n    }\\n    return colorArray1.slice(1).every((c, i) => c === colorArray2[i + 1]);\\n  }\\n}\\n\\n;// ./src/scripting_api/field.js\\n\\n\\n\\nclass Field extends PDFObject {\\n  constructor(data) {\\n    super(data);\\n    this.alignment = data.alignment || \\\"left\\\";\\n    this.borderStyle = data.borderStyle || \\\"\\\";\\n    this.buttonAlignX = data.buttonAlignX || 50;\\n    this.buttonAlignY = data.buttonAlignY || 50;\\n    this.buttonFitBounds = data.buttonFitBounds;\\n    this.buttonPosition = data.buttonPosition;\\n    this.buttonScaleHow = data.buttonScaleHow;\\n    this.ButtonScaleWhen = data.buttonScaleWhen;\\n    this.calcOrderIndex = data.calcOrderIndex;\\n    this.comb = data.comb;\\n    this.commitOnSelChange = data.commitOnSelChange;\\n    this.currentValueIndices = data.currentValueIndices;\\n    this.defaultStyle = data.defaultStyle;\\n    this.defaultValue = data.defaultValue;\\n    this.doNotScroll = data.doNotScroll;\\n    this.doNotSpellCheck = data.doNotSpellCheck;\\n    this.delay = data.delay;\\n    this.display = data.display;\\n    this.doc = data.doc.wrapped;\\n    this.editable = data.editable;\\n    this.exportValues = data.exportValues;\\n    this.fileSelect = data.fileSelect;\\n    this.hidden = data.hidden;\\n    this.highlight = data.highlight;\\n    this.lineWidth = data.lineWidth;\\n    this.multiline = data.multiline;\\n    this.multipleSelection = !!data.multipleSelection;\\n    this.name = data.name;\\n    this.password = data.password;\\n    this.print = data.print;\\n    this.radiosInUnison = data.radiosInUnison;\\n    this.readonly = data.readonly;\\n    this.rect = data.rect;\\n    this.required = data.required;\\n    this.richText = data.richText;\\n    this.richValue = data.richValue;\\n    this.style = data.style;\\n    this.submitName = data.submitName;\\n    this.textFont = data.textFont;\\n    this.textSize = data.textSize;\\n    this.type = data.type;\\n    this.userName = data.userName;\\n    this._actions = createActionsMap(data.actions);\\n    this._browseForFileToSubmit = data.browseForFileToSubmit || null;\\n    this._buttonCaption = null;\\n    this._buttonIcon = null;\\n    this._charLimit = data.charLimit;\\n    this._children = null;\\n    this._currentValueIndices = data.currentValueIndices || 0;\\n    this._document = data.doc;\\n    this._fieldPath = data.fieldPath;\\n    this._fillColor = data.fillColor || [\\\"T\\\"];\\n    this._isChoice = Array.isArray(data.items);\\n    this._items = data.items || [];\\n    this._hasValue = data.hasOwnProperty(\\\"value\\\");\\n    this._page = data.page || 0;\\n    this._strokeColor = data.strokeColor || [\\\"G\\\", 0];\\n    this._textColor = data.textColor || [\\\"G\\\", 0];\\n    this._value = null;\\n    this._kidIds = data.kidIds || null;\\n    this._fieldType = getFieldType(this._actions);\\n    this._siblings = data.siblings || null;\\n    this._rotation = data.rotation || 0;\\n    this._globalEval = data.globalEval;\\n    this._appObjects = data.appObjects;\\n    this.value = data.value || \\\"\\\";\\n  }\\n  get currentValueIndices() {\\n    if (!this._isChoice) {\\n      return 0;\\n    }\\n    return this._currentValueIndices;\\n  }\\n  set currentValueIndices(indices) {\\n    if (!this._isChoice) {\\n      return;\\n    }\\n    if (!Array.isArray(indices)) {\\n      indices = [indices];\\n    }\\n    if (!indices.every(i => typeof i === \\\"number\\\" && Number.isInteger(i) && i >= 0 && i < this.numItems)) {\\n      return;\\n    }\\n    indices.sort();\\n    if (this.multipleSelection) {\\n      this._currentValueIndices = indices;\\n      this._value = [];\\n      indices.forEach(i => {\\n        this._value.push(this._items[i].displayValue);\\n      });\\n    } else if (indices.length > 0) {\\n      indices = indices.splice(1, indices.length - 1);\\n      this._currentValueIndices = indices[0];\\n      this._value = this._items[this._currentValueIndices];\\n    }\\n    this._send({\\n      id: this._id,\\n      indices\\n    });\\n  }\\n  get fillColor() {\\n    return this._fillColor;\\n  }\\n  set fillColor(color) {\\n    if (Color._isValidColor(color)) {\\n      this._fillColor = color;\\n    }\\n  }\\n  get bgColor() {\\n    return this.fillColor;\\n  }\\n  set bgColor(color) {\\n    this.fillColor = color;\\n  }\\n  get charLimit() {\\n    return this._charLimit;\\n  }\\n  set charLimit(limit) {\\n    if (typeof limit !== \\\"number\\\") {\\n      throw new Error(\\\"Invalid argument value\\\");\\n    }\\n    this._charLimit = Math.max(0, Math.floor(limit));\\n  }\\n  get numItems() {\\n    if (!this._isChoice) {\\n      throw new Error(\\\"Not a choice widget\\\");\\n    }\\n    return this._items.length;\\n  }\\n  set numItems(_) {\\n    throw new Error(\\\"field.numItems is read-only\\\");\\n  }\\n  get strokeColor() {\\n    return this._strokeColor;\\n  }\\n  set strokeColor(color) {\\n    if (Color._isValidColor(color)) {\\n      this._strokeColor = color;\\n    }\\n  }\\n  get borderColor() {\\n    return this.strokeColor;\\n  }\\n  set borderColor(color) {\\n    this.strokeColor = color;\\n  }\\n  get page() {\\n    return this._page;\\n  }\\n  set page(_) {\\n    throw new Error(\\\"field.page is read-only\\\");\\n  }\\n  get rotation() {\\n    return this._rotation;\\n  }\\n  set rotation(angle) {\\n    angle = Math.floor(angle);\\n    if (angle % 90 !== 0) {\\n      throw new Error(\\\"Invalid rotation: must be a multiple of 90\\\");\\n    }\\n    angle %= 360;\\n    if (angle < 0) {\\n      angle += 360;\\n    }\\n    this._rotation = angle;\\n  }\\n  get textColor() {\\n    return this._textColor;\\n  }\\n  set textColor(color) {\\n    if (Color._isValidColor(color)) {\\n      this._textColor = color;\\n    }\\n  }\\n  get fgColor() {\\n    return this.textColor;\\n  }\\n  set fgColor(color) {\\n    this.textColor = color;\\n  }\\n  get value() {\\n    return this._value;\\n  }\\n  set value(value) {\\n    if (this._isChoice) {\\n      this._setChoiceValue(value);\\n      return;\\n    }\\n    if (value === \\\"\\\" || typeof value !== \\\"string\\\" || this._fieldType >= FieldType.date) {\\n      this._originalValue = undefined;\\n      this._value = value;\\n      return;\\n    }\\n    this._originalValue = value;\\n    const _value = value.trim().replace(\\\",\\\", \\\".\\\");\\n    this._value = !isNaN(_value) ? parseFloat(_value) : value;\\n  }\\n  _getValue() {\\n    return this._originalValue ?? this.value;\\n  }\\n  _setChoiceValue(value) {\\n    if (this.multipleSelection) {\\n      if (!Array.isArray(value)) {\\n        value = [value];\\n      }\\n      const values = new Set(value);\\n      if (Array.isArray(this._currentValueIndices)) {\\n        this._currentValueIndices.length = 0;\\n        this._value.length = 0;\\n      } else {\\n        this._currentValueIndices = [];\\n        this._value = [];\\n      }\\n      this._items.forEach((item, i) => {\\n        if (values.has(item.exportValue)) {\\n          this._currentValueIndices.push(i);\\n          this._value.push(item.exportValue);\\n        }\\n      });\\n    } else {\\n      if (Array.isArray(value)) {\\n        value = value[0];\\n      }\\n      const index = this._items.findIndex(({\\n        exportValue\\n      }) => value === exportValue);\\n      if (index !== -1) {\\n        this._currentValueIndices = index;\\n        this._value = this._items[index].exportValue;\\n      }\\n    }\\n  }\\n  get valueAsString() {\\n    return (this._value ?? \\\"\\\").toString();\\n  }\\n  set valueAsString(_) {}\\n  browseForFileToSubmit() {\\n    if (this._browseForFileToSubmit) {\\n      this._browseForFileToSubmit();\\n    }\\n  }\\n  buttonGetCaption(nFace = 0) {\\n    if (this._buttonCaption) {\\n      return this._buttonCaption[nFace];\\n    }\\n    return \\\"\\\";\\n  }\\n  buttonGetIcon(nFace = 0) {\\n    if (this._buttonIcon) {\\n      return this._buttonIcon[nFace];\\n    }\\n    return null;\\n  }\\n  buttonImportIcon(cPath = null, nPave = 0) {}\\n  buttonSetCaption(cCaption, nFace = 0) {\\n    if (!this._buttonCaption) {\\n      this._buttonCaption = [\\\"\\\", \\\"\\\", \\\"\\\"];\\n    }\\n    this._buttonCaption[nFace] = cCaption;\\n  }\\n  buttonSetIcon(oIcon, nFace = 0) {\\n    if (!this._buttonIcon) {\\n      this._buttonIcon = [null, null, null];\\n    }\\n    this._buttonIcon[nFace] = oIcon;\\n  }\\n  checkThisBox(nWidget, bCheckIt = true) {}\\n  clearItems() {\\n    if (!this._isChoice) {\\n      throw new Error(\\\"Not a choice widget\\\");\\n    }\\n    this._items = [];\\n    this._send({\\n      id: this._id,\\n      clear: null\\n    });\\n  }\\n  deleteItemAt(nIdx = null) {\\n    if (!this._isChoice) {\\n      throw new Error(\\\"Not a choice widget\\\");\\n    }\\n    if (!this.numItems) {\\n      return;\\n    }\\n    if (nIdx === null) {\\n      nIdx = Array.isArray(this._currentValueIndices) ? this._currentValueIndices[0] : this._currentValueIndices;\\n      nIdx ||= 0;\\n    }\\n    if (nIdx < 0 || nIdx >= this.numItems) {\\n      nIdx = this.numItems - 1;\\n    }\\n    this._items.splice(nIdx, 1);\\n    if (Array.isArray(this._currentValueIndices)) {\\n      let index = this._currentValueIndices.findIndex(i => i >= nIdx);\\n      if (index !== -1) {\\n        if (this._currentValueIndices[index] === nIdx) {\\n          this._currentValueIndices.splice(index, 1);\\n        }\\n        for (const ii = this._currentValueIndices.length; index < ii; index++) {\\n          --this._currentValueIndices[index];\\n        }\\n      }\\n    } else if (this._currentValueIndices === nIdx) {\\n      this._currentValueIndices = this.numItems > 0 ? 0 : -1;\\n    } else if (this._currentValueIndices > nIdx) {\\n      --this._currentValueIndices;\\n    }\\n    this._send({\\n      id: this._id,\\n      remove: nIdx\\n    });\\n  }\\n  getItemAt(nIdx = -1, bExportValue = false) {\\n    if (!this._isChoice) {\\n      throw new Error(\\\"Not a choice widget\\\");\\n    }\\n    if (nIdx < 0 || nIdx >= this.numItems) {\\n      nIdx = this.numItems - 1;\\n    }\\n    const item = this._items[nIdx];\\n    return bExportValue ? item.exportValue : item.displayValue;\\n  }\\n  getArray() {\\n    if (this._kidIds) {\\n      const array = [];\\n      const fillArrayWithKids = kidIds => {\\n        for (const id of kidIds) {\\n          const obj = this._appObjects[id];\\n          if (!obj) {\\n            continue;\\n          }\\n          if (obj.obj._hasValue) {\\n            array.push(obj.wrapped);\\n          }\\n          if (obj.obj._kidIds) {\\n            fillArrayWithKids(obj.obj._kidIds);\\n          }\\n        }\\n      };\\n      fillArrayWithKids(this._kidIds);\\n      return array;\\n    }\\n    if (this._children === null) {\\n      this._children = this._document.obj._getTerminalChildren(this._fieldPath);\\n    }\\n    return this._children;\\n  }\\n  getLock() {\\n    return undefined;\\n  }\\n  isBoxChecked(nWidget) {\\n    return false;\\n  }\\n  isDefaultChecked(nWidget) {\\n    return false;\\n  }\\n  insertItemAt(cName, cExport = undefined, nIdx = 0) {\\n    if (!this._isChoice) {\\n      throw new Error(\\\"Not a choice widget\\\");\\n    }\\n    if (!cName) {\\n      return;\\n    }\\n    if (nIdx < 0 || nIdx > this.numItems) {\\n      nIdx = this.numItems;\\n    }\\n    if (this._items.some(({\\n      displayValue\\n    }) => displayValue === cName)) {\\n      return;\\n    }\\n    if (cExport === undefined) {\\n      cExport = cName;\\n    }\\n    const data = {\\n      displayValue: cName,\\n      exportValue: cExport\\n    };\\n    this._items.splice(nIdx, 0, data);\\n    if (Array.isArray(this._currentValueIndices)) {\\n      let index = this._currentValueIndices.findIndex(i => i >= nIdx);\\n      if (index !== -1) {\\n        for (const ii = this._currentValueIndices.length; index < ii; index++) {\\n          ++this._currentValueIndices[index];\\n        }\\n      }\\n    } else if (this._currentValueIndices >= nIdx) {\\n      ++this._currentValueIndices;\\n    }\\n    this._send({\\n      id: this._id,\\n      insert: {\\n        index: nIdx,\\n        ...data\\n      }\\n    });\\n  }\\n  setAction(cTrigger, cScript) {\\n    if (typeof cTrigger !== \\\"string\\\" || typeof cScript !== \\\"string\\\") {\\n      return;\\n    }\\n    if (!(cTrigger in this._actions)) {\\n      this._actions[cTrigger] = [];\\n    }\\n    this._actions[cTrigger].push(cScript);\\n  }\\n  setFocus() {\\n    this._send({\\n      id: this._id,\\n      focus: true\\n    });\\n  }\\n  setItems(oArray) {\\n    if (!this._isChoice) {\\n      throw new Error(\\\"Not a choice widget\\\");\\n    }\\n    this._items.length = 0;\\n    for (const element of oArray) {\\n      let displayValue, exportValue;\\n      if (Array.isArray(element)) {\\n        displayValue = element[0]?.toString() || \\\"\\\";\\n        exportValue = element[1]?.toString() || \\\"\\\";\\n      } else {\\n        displayValue = exportValue = element?.toString() || \\\"\\\";\\n      }\\n      this._items.push({\\n        displayValue,\\n        exportValue\\n      });\\n    }\\n    this._currentValueIndices = 0;\\n    this._send({\\n      id: this._id,\\n      items: this._items\\n    });\\n  }\\n  setLock() {}\\n  signatureGetModifications() {}\\n  signatureGetSeedValue() {}\\n  signatureInfo() {}\\n  signatureSetSeedValue() {}\\n  signatureSign() {}\\n  signatureValidate() {}\\n  _isButton() {\\n    return false;\\n  }\\n  _reset() {\\n    this.value = this.defaultValue;\\n  }\\n  _runActions(event) {\\n    const eventName = event.name;\\n    if (!this._actions.has(eventName)) {\\n      return false;\\n    }\\n    const actions = this._actions.get(eventName);\\n    try {\\n      for (const action of actions) {\\n        this._globalEval(action);\\n      }\\n    } catch (error) {\\n      event.rc = false;\\n      throw error;\\n    }\\n    return true;\\n  }\\n}\\nclass RadioButtonField extends Field {\\n  constructor(otherButtons, data) {\\n    super(data);\\n    this.exportValues = [this.exportValues];\\n    this._radioIds = [this._id];\\n    this._radioActions = [this._actions];\\n    for (const radioData of otherButtons) {\\n      this.exportValues.push(radioData.exportValues);\\n      this._radioIds.push(radioData.id);\\n      this._radioActions.push(createActionsMap(radioData.actions));\\n      if (this._value === radioData.exportValues) {\\n        this._id = radioData.id;\\n      }\\n    }\\n    this._hasBeenInitialized = true;\\n    this._value = data.value || \\\"\\\";\\n  }\\n  get value() {\\n    return this._value;\\n  }\\n  set value(value) {\\n    if (!this._hasBeenInitialized) {\\n      return;\\n    }\\n    if (value === null || value === undefined) {\\n      this._value = \\\"\\\";\\n    }\\n    const i = this.exportValues.indexOf(value);\\n    if (0 <= i && i < this._radioIds.length) {\\n      this._id = this._radioIds[i];\\n      this._value = value;\\n    } else if (value === \\\"Off\\\" && this._radioIds.length === 2) {\\n      const nextI = (1 + this._radioIds.indexOf(this._id)) % 2;\\n      this._id = this._radioIds[nextI];\\n      this._value = this.exportValues[nextI];\\n    }\\n  }\\n  checkThisBox(nWidget, bCheckIt = true) {\\n    if (nWidget < 0 || nWidget >= this._radioIds.length || !bCheckIt) {\\n      return;\\n    }\\n    this._id = this._radioIds[nWidget];\\n    this._value = this.exportValues[nWidget];\\n    this._send({\\n      id: this._id,\\n      value: this._value\\n    });\\n  }\\n  isBoxChecked(nWidget) {\\n    return nWidget >= 0 && nWidget < this._radioIds.length && this._id === this._radioIds[nWidget];\\n  }\\n  isDefaultChecked(nWidget) {\\n    return nWidget >= 0 && nWidget < this.exportValues.length && this.defaultValue === this.exportValues[nWidget];\\n  }\\n  _getExportValue(state) {\\n    const i = this._radioIds.indexOf(this._id);\\n    return this.exportValues[i];\\n  }\\n  _runActions(event) {\\n    const i = this._radioIds.indexOf(this._id);\\n    this._actions = this._radioActions[i];\\n    return super._runActions(event);\\n  }\\n  _isButton() {\\n    return true;\\n  }\\n}\\nclass CheckboxField extends RadioButtonField {\\n  get value() {\\n    return this._value;\\n  }\\n  set value(value) {\\n    if (!value || value === \\\"Off\\\") {\\n      this._value = \\\"Off\\\";\\n    } else {\\n      super.value = value;\\n    }\\n  }\\n  _getExportValue(state) {\\n    return state ? super._getExportValue(state) : \\\"Off\\\";\\n  }\\n  isBoxChecked(nWidget) {\\n    if (this._value === \\\"Off\\\") {\\n      return false;\\n    }\\n    return super.isBoxChecked(nWidget);\\n  }\\n  isDefaultChecked(nWidget) {\\n    if (this.defaultValue === \\\"Off\\\") {\\n      return this._value === \\\"Off\\\";\\n    }\\n    return super.isDefaultChecked(nWidget);\\n  }\\n  checkThisBox(nWidget, bCheckIt = true) {\\n    if (nWidget < 0 || nWidget >= this._radioIds.length) {\\n      return;\\n    }\\n    this._id = this._radioIds[nWidget];\\n    this._value = bCheckIt ? this.exportValues[nWidget] : \\\"Off\\\";\\n    this._send({\\n      id: this._id,\\n      value: this._value\\n    });\\n  }\\n}\\n\\n;// ./src/scripting_api/aform.js\\n\\nclass AForm {\\n  constructor(document, app, util, color) {\\n    this._document = document;\\n    this._app = app;\\n    this._util = util;\\n    this._color = color;\\n    this._dateFormats = [\\\"m/d\\\", \\\"m/d/yy\\\", \\\"mm/dd/yy\\\", \\\"mm/yy\\\", \\\"d-mmm\\\", \\\"d-mmm-yy\\\", \\\"dd-mmm-yy\\\", \\\"yy-mm-dd\\\", \\\"mmm-yy\\\", \\\"mmmm-yy\\\", \\\"mmm d, yyyy\\\", \\\"mmmm d, yyyy\\\", \\\"m/d/yy h:MM tt\\\", \\\"m/d/yy HH:MM\\\"];\\n    this._timeFormats = [\\\"HH:MM\\\", \\\"h:MM tt\\\", \\\"HH:MM:ss\\\", \\\"h:MM:ss tt\\\"];\\n    this._dateActionsCache = new Map();\\n    this._emailRegex = new RegExp(\\\"^[a-zA-Z0-9.!#$%&'*+\\\\\\\\/=?^_`{|}~-]+\\\" + \\\"@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\\" + \\\"(?:\\\\\\\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$\\\");\\n  }\\n  _mkTargetName(event) {\\n    return event.target ? `[ ${event.target.name} ]` : \\\"\\\";\\n  }\\n  _tryToGuessDate(cFormat, cDate) {\\n    let actions = this._dateActionsCache.get(cFormat);\\n    if (!actions) {\\n      actions = [];\\n      this._dateActionsCache.set(cFormat, actions);\\n      cFormat.replaceAll(/(d+)|(m+)|(y+)|(H+)|(M+)|(s+)/g, function (match, d, m, y, H, M, s) {\\n        if (d) {\\n          actions.push((n, date) => {\\n            if (n >= 1 && n <= 31) {\\n              date.setDate(n);\\n              return true;\\n            }\\n            return false;\\n          });\\n        } else if (m) {\\n          actions.push((n, date) => {\\n            if (n >= 1 && n <= 12) {\\n              date.setMonth(n - 1);\\n              return true;\\n            }\\n            return false;\\n          });\\n        } else if (y) {\\n          actions.push((n, date) => {\\n            if (n < 50) {\\n              n += 2000;\\n            } else if (n < 100) {\\n              n += 1900;\\n            }\\n            date.setYear(n);\\n            return true;\\n          });\\n        } else if (H) {\\n          actions.push((n, date) => {\\n            if (n >= 0 && n <= 23) {\\n              date.setHours(n);\\n              return true;\\n            }\\n            return false;\\n          });\\n        } else if (M) {\\n          actions.push((n, date) => {\\n            if (n >= 0 && n <= 59) {\\n              date.setMinutes(n);\\n              return true;\\n            }\\n            return false;\\n          });\\n        } else if (s) {\\n          actions.push((n, date) => {\\n            if (n >= 0 && n <= 59) {\\n              date.setSeconds(n);\\n              return true;\\n            }\\n            return false;\\n          });\\n        }\\n        return \\\"\\\";\\n      });\\n    }\\n    const number = /\\\\d+/g;\\n    let i = 0;\\n    let array;\\n    const date = new Date();\\n    while ((array = number.exec(cDate)) !== null) {\\n      if (i < actions.length) {\\n        if (!actions[i++](parseInt(array[0]), date)) {\\n          return null;\\n        }\\n      } else {\\n        break;\\n      }\\n    }\\n    if (i === 0) {\\n      return null;\\n    }\\n    return date;\\n  }\\n  _parseDate(cFormat, cDate) {\\n    let date = null;\\n    try {\\n      date = this._util.scand(cFormat, cDate);\\n    } catch {}\\n    if (!date) {\\n      date = Date.parse(cDate);\\n      date = isNaN(date) ? this._tryToGuessDate(cFormat, cDate) : new Date(date);\\n    }\\n    return date;\\n  }\\n  AFMergeChange(event = globalThis.event) {\\n    if (event.willCommit) {\\n      return event.value.toString();\\n    }\\n    return this._app._eventDispatcher.mergeChange(event);\\n  }\\n  AFParseDateEx(cString, cOrder) {\\n    return this._parseDate(cOrder, cString);\\n  }\\n  AFExtractNums(str) {\\n    if (typeof str === \\\"number\\\") {\\n      return [str];\\n    }\\n    if (!str || typeof str !== \\\"string\\\") {\\n      return null;\\n    }\\n    const first = str.charAt(0);\\n    if (first === \\\".\\\" || first === \\\",\\\") {\\n      str = `0${str}`;\\n    }\\n    const numbers = str.match(/(\\\\d+)/g);\\n    if (numbers.length === 0) {\\n      return null;\\n    }\\n    return numbers;\\n  }\\n  AFMakeNumber(str) {\\n    if (typeof str === \\\"number\\\") {\\n      return str;\\n    }\\n    if (typeof str !== \\\"string\\\") {\\n      return null;\\n    }\\n    str = str.trim().replace(\\\",\\\", \\\".\\\");\\n    const number = parseFloat(str);\\n    if (isNaN(number) || !isFinite(number)) {\\n      return null;\\n    }\\n    return number;\\n  }\\n  AFMakeArrayFromList(string) {\\n    if (typeof string === \\\"string\\\") {\\n      return string.split(/, ?/g);\\n    }\\n    return string;\\n  }\\n  AFNumber_Format(nDec, sepStyle, negStyle, currStyle, strCurrency, bCurrencyPrepend) {\\n    const event = globalThis.event;\\n    let value = this.AFMakeNumber(event.value);\\n    if (value === null) {\\n      event.value = \\\"\\\";\\n      return;\\n    }\\n    const sign = Math.sign(value);\\n    const buf = [];\\n    let hasParen = false;\\n    if (sign === -1 && bCurrencyPrepend && negStyle === 0) {\\n      buf.push(\\\"-\\\");\\n    }\\n    if ((negStyle === 2 || negStyle === 3) && sign === -1) {\\n      buf.push(\\\"(\\\");\\n      hasParen = true;\\n    }\\n    if (bCurrencyPrepend) {\\n      buf.push(strCurrency);\\n    }\\n    sepStyle = Math.min(Math.max(0, Math.floor(sepStyle)), 4);\\n    buf.push(\\\"%,\\\", sepStyle, \\\".\\\", nDec.toString(), \\\"f\\\");\\n    if (!bCurrencyPrepend) {\\n      buf.push(strCurrency);\\n    }\\n    if (hasParen) {\\n      buf.push(\\\")\\\");\\n    }\\n    if (negStyle === 1 || negStyle === 3) {\\n      event.target.textColor = sign === 1 ? this._color.black : this._color.red;\\n    }\\n    if ((negStyle !== 0 || bCurrencyPrepend) && sign === -1) {\\n      value = -value;\\n    }\\n    const formatStr = buf.join(\\\"\\\");\\n    event.value = this._util.printf(formatStr, value);\\n  }\\n  AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency, bCurrencyPrepend) {\\n    const event = globalThis.event;\\n    let value = this.AFMergeChange(event);\\n    if (!value) {\\n      return;\\n    }\\n    value = value.trim();\\n    let pattern;\\n    if (sepStyle > 1) {\\n      pattern = event.willCommit ? /^[+-]?(\\\\d+(,\\\\d*)?|,\\\\d+)$/ : /^[+-]?\\\\d*,?\\\\d*$/;\\n    } else {\\n      pattern = event.willCommit ? /^[+-]?(\\\\d+(\\\\.\\\\d*)?|\\\\.\\\\d+)$/ : /^[+-]?\\\\d*\\\\.?\\\\d*$/;\\n    }\\n    if (!pattern.test(value)) {\\n      if (event.willCommit) {\\n        const err = `${GlobalConstants.IDS_INVALID_VALUE} ${this._mkTargetName(event)}`;\\n        this._app.alert(err);\\n      }\\n      event.rc = false;\\n    }\\n    if (event.willCommit && sepStyle > 1) {\\n      event.value = parseFloat(value.replace(\\\",\\\", \\\".\\\"));\\n    }\\n  }\\n  AFPercent_Format(nDec, sepStyle, percentPrepend = false) {\\n    if (typeof nDec !== \\\"number\\\") {\\n      return;\\n    }\\n    if (typeof sepStyle !== \\\"number\\\") {\\n      return;\\n    }\\n    if (nDec < 0) {\\n      throw new Error(\\\"Invalid nDec value in AFPercent_Format\\\");\\n    }\\n    const event = globalThis.event;\\n    if (nDec > 512) {\\n      event.value = \\\"%\\\";\\n      return;\\n    }\\n    nDec = Math.floor(nDec);\\n    sepStyle = Math.min(Math.max(0, Math.floor(sepStyle)), 4);\\n    let value = this.AFMakeNumber(event.value);\\n    if (value === null) {\\n      event.value = \\\"%\\\";\\n      return;\\n    }\\n    const formatStr = `%,${sepStyle}.${nDec}f`;\\n    value = this._util.printf(formatStr, value * 100);\\n    event.value = percentPrepend ? `%${value}` : `${value}%`;\\n  }\\n  AFPercent_Keystroke(nDec, sepStyle) {\\n    this.AFNumber_Keystroke(nDec, sepStyle, 0, 0, \\\"\\\", true);\\n  }\\n  AFDate_FormatEx(cFormat) {\\n    const event = globalThis.event;\\n    const value = event.value;\\n    if (!value) {\\n      return;\\n    }\\n    const date = this._parseDate(cFormat, value);\\n    if (date !== null) {\\n      event.value = this._util.printd(cFormat, date);\\n    }\\n  }\\n  AFDate_Format(pdf) {\\n    if (pdf >= 0 && pdf < this._dateFormats.length) {\\n      this.AFDate_FormatEx(this._dateFormats[pdf]);\\n    }\\n  }\\n  AFDate_KeystrokeEx(cFormat) {\\n    const event = globalThis.event;\\n    if (!event.willCommit) {\\n      return;\\n    }\\n    const value = this.AFMergeChange(event);\\n    if (!value) {\\n      return;\\n    }\\n    if (this._parseDate(cFormat, value) === null) {\\n      const invalid = GlobalConstants.IDS_INVALID_DATE;\\n      const invalid2 = GlobalConstants.IDS_INVALID_DATE2;\\n      const err = `${invalid} ${this._mkTargetName(event)}${invalid2}${cFormat}`;\\n      this._app.alert(err);\\n      event.rc = false;\\n    }\\n  }\\n  AFDate_Keystroke(pdf) {\\n    if (pdf >= 0 && pdf < this._dateFormats.length) {\\n      this.AFDate_KeystrokeEx(this._dateFormats[pdf]);\\n    }\\n  }\\n  AFRange_Validate(bGreaterThan, nGreaterThan, bLessThan, nLessThan) {\\n    const event = globalThis.event;\\n    if (!event.value) {\\n      return;\\n    }\\n    const value = this.AFMakeNumber(event.value);\\n    if (value === null) {\\n      return;\\n    }\\n    bGreaterThan = !!bGreaterThan;\\n    bLessThan = !!bLessThan;\\n    if (bGreaterThan) {\\n      nGreaterThan = this.AFMakeNumber(nGreaterThan);\\n      if (nGreaterThan === null) {\\n        return;\\n      }\\n    }\\n    if (bLessThan) {\\n      nLessThan = this.AFMakeNumber(nLessThan);\\n      if (nLessThan === null) {\\n        return;\\n      }\\n    }\\n    let err = \\\"\\\";\\n    if (bGreaterThan && bLessThan) {\\n      if (value < nGreaterThan || value > nLessThan) {\\n        err = this._util.printf(GlobalConstants.IDS_GT_AND_LT, nGreaterThan, nLessThan);\\n      }\\n    } else if (bGreaterThan) {\\n      if (value < nGreaterThan) {\\n        err = this._util.printf(GlobalConstants.IDS_GREATER_THAN, nGreaterThan);\\n      }\\n    } else if (value > nLessThan) {\\n      err = this._util.printf(GlobalConstants.IDS_LESS_THAN, nLessThan);\\n    }\\n    if (err) {\\n      this._app.alert(err);\\n      event.rc = false;\\n    }\\n  }\\n  AFSimple(cFunction, nValue1, nValue2) {\\n    const value1 = this.AFMakeNumber(nValue1);\\n    if (value1 === null) {\\n      throw new Error(\\\"Invalid nValue1 in AFSimple\\\");\\n    }\\n    const value2 = this.AFMakeNumber(nValue2);\\n    if (value2 === null) {\\n      throw new Error(\\\"Invalid nValue2 in AFSimple\\\");\\n    }\\n    switch (cFunction) {\\n      case \\\"AVG\\\":\\n        return (value1 + value2) / 2;\\n      case \\\"SUM\\\":\\n        return value1 + value2;\\n      case \\\"PRD\\\":\\n        return value1 * value2;\\n      case \\\"MIN\\\":\\n        return Math.min(value1, value2);\\n      case \\\"MAX\\\":\\n        return Math.max(value1, value2);\\n    }\\n    throw new Error(\\\"Invalid cFunction in AFSimple\\\");\\n  }\\n  AFSimple_Calculate(cFunction, cFields) {\\n    const actions = {\\n      AVG: args => args.reduce((acc, value) => acc + value, 0) / args.length,\\n      SUM: args => args.reduce((acc, value) => acc + value, 0),\\n      PRD: args => args.reduce((acc, value) => acc * value, 1),\\n      MIN: args => args.reduce((acc, value) => Math.min(acc, value), Number.MAX_VALUE),\\n      MAX: args => args.reduce((acc, value) => Math.max(acc, value), Number.MIN_VALUE)\\n    };\\n    if (!(cFunction in actions)) {\\n      throw new TypeError(\\\"Invalid function in AFSimple_Calculate\\\");\\n    }\\n    const event = globalThis.event;\\n    const values = [];\\n    cFields = this.AFMakeArrayFromList(cFields);\\n    for (const cField of cFields) {\\n      const field = this._document.getField(cField);\\n      if (!field) {\\n        continue;\\n      }\\n      for (const child of field.getArray()) {\\n        const number = this.AFMakeNumber(child.value);\\n        if (number !== null) {\\n          values.push(number);\\n        }\\n      }\\n    }\\n    if (values.length === 0) {\\n      event.value = cFunction === \\\"PRD\\\" ? 1 : 0;\\n      return;\\n    }\\n    const res = actions[cFunction](values);\\n    event.value = Math.round(1e6 * res) / 1e6;\\n  }\\n  AFSpecial_Format(psf) {\\n    const event = globalThis.event;\\n    if (!event.value) {\\n      return;\\n    }\\n    psf = this.AFMakeNumber(psf);\\n    let formatStr;\\n    switch (psf) {\\n      case 0:\\n        formatStr = \\\"99999\\\";\\n        break;\\n      case 1:\\n        formatStr = \\\"99999-9999\\\";\\n        break;\\n      case 2:\\n        formatStr = this._util.printx(\\\"9999999999\\\", event.value).length >= 10 ? \\\"(999) 999-9999\\\" : \\\"999-9999\\\";\\n        break;\\n      case 3:\\n        formatStr = \\\"999-99-9999\\\";\\n        break;\\n      default:\\n        throw new Error(\\\"Invalid psf in AFSpecial_Format\\\");\\n    }\\n    event.value = this._util.printx(formatStr, event.value);\\n  }\\n  AFSpecial_KeystrokeEx(cMask) {\\n    if (!cMask) {\\n      return;\\n    }\\n    const event = globalThis.event;\\n    const value = this.AFMergeChange(event);\\n    if (!value) {\\n      return;\\n    }\\n    const checkers = new Map([[\\\"9\\\", char => char >= \\\"0\\\" && char <= \\\"9\\\"], [\\\"A\\\", char => \\\"a\\\" <= char && char <= \\\"z\\\" || \\\"A\\\" <= char && char <= \\\"Z\\\"], [\\\"O\\\", char => \\\"a\\\" <= char && char <= \\\"z\\\" || \\\"A\\\" <= char && char <= \\\"Z\\\" || \\\"0\\\" <= char && char <= \\\"9\\\"], [\\\"X\\\", char => true]]);\\n    function _checkValidity(_value, _cMask) {\\n      for (let i = 0, ii = _value.length; i < ii; i++) {\\n        const mask = _cMask.charAt(i);\\n        const char = _value.charAt(i);\\n        const checker = checkers.get(mask);\\n        if (checker) {\\n          if (!checker(char)) {\\n            return false;\\n          }\\n        } else if (mask !== char) {\\n          return false;\\n        }\\n      }\\n      return true;\\n    }\\n    const err = `${GlobalConstants.IDS_INVALID_VALUE} = \\\"${cMask}\\\"`;\\n    if (value.length > cMask.length) {\\n      this._app.alert(err);\\n      event.rc = false;\\n      return;\\n    }\\n    if (event.willCommit) {\\n      if (value.length < cMask.length) {\\n        this._app.alert(err);\\n        event.rc = false;\\n        return;\\n      }\\n      if (!_checkValidity(value, cMask)) {\\n        this._app.alert(err);\\n        event.rc = false;\\n        return;\\n      }\\n      event.value += cMask.substring(value.length);\\n      return;\\n    }\\n    if (value.length < cMask.length) {\\n      cMask = cMask.substring(0, value.length);\\n    }\\n    if (!_checkValidity(value, cMask)) {\\n      this._app.alert(err);\\n      event.rc = false;\\n    }\\n  }\\n  AFSpecial_Keystroke(psf) {\\n    const event = globalThis.event;\\n    psf = this.AFMakeNumber(psf);\\n    let formatStr;\\n    switch (psf) {\\n      case 0:\\n        formatStr = \\\"99999\\\";\\n        break;\\n      case 1:\\n        formatStr = \\\"99999-9999\\\";\\n        break;\\n      case 2:\\n        const value = this.AFMergeChange(event);\\n        formatStr = value.length > 8 || value.startsWith(\\\"(\\\") ? \\\"(999) 999-9999\\\" : \\\"999-9999\\\";\\n        break;\\n      case 3:\\n        formatStr = \\\"999-99-9999\\\";\\n        break;\\n      default:\\n        throw new Error(\\\"Invalid psf in AFSpecial_Keystroke\\\");\\n    }\\n    this.AFSpecial_KeystrokeEx(formatStr);\\n  }\\n  AFTime_FormatEx(cFormat) {\\n    this.AFDate_FormatEx(cFormat);\\n  }\\n  AFTime_Format(pdf) {\\n    if (pdf >= 0 && pdf < this._timeFormats.length) {\\n      this.AFDate_FormatEx(this._timeFormats[pdf]);\\n    }\\n  }\\n  AFTime_KeystrokeEx(cFormat) {\\n    this.AFDate_KeystrokeEx(cFormat);\\n  }\\n  AFTime_Keystroke(pdf) {\\n    if (pdf >= 0 && pdf < this._timeFormats.length) {\\n      this.AFDate_KeystrokeEx(this._timeFormats[pdf]);\\n    }\\n  }\\n  eMailValidate(str) {\\n    return this._emailRegex.test(str);\\n  }\\n  AFExactMatch(rePatterns, str) {\\n    if (rePatterns instanceof RegExp) {\\n      return str.match(rePatterns)?.[0] === str || 0;\\n    }\\n    return rePatterns.findIndex(re => str.match(re)?.[0] === str) + 1;\\n  }\\n}\\n\\n;// ./src/scripting_api/app_utils.js\\nconst VIEWER_TYPE = \\\"PDF.js\\\";\\nconst VIEWER_VARIATION = \\\"Full\\\";\\nconst VIEWER_VERSION = 21.00720099;\\nconst FORMS_VERSION = 21.00720099;\\nconst USERACTIVATION_CALLBACKID = 0;\\nconst USERACTIVATION_MAXTIME_VALIDITY = 5000;\\nfunction serializeError(error) {\\n  const value = `${error.toString()}\\\\n${error.stack}`;\\n  return {\\n    command: \\\"error\\\",\\n    value\\n  };\\n}\\n\\n;// ./src/scripting_api/event.js\\n\\nclass Event {\\n  constructor(data) {\\n    this.change = data.change || \\\"\\\";\\n    this.changeEx = data.changeEx || null;\\n    this.commitKey = data.commitKey || 0;\\n    this.fieldFull = data.fieldFull || false;\\n    this.keyDown = data.keyDown || false;\\n    this.modifier = data.modifier || false;\\n    this.name = data.name;\\n    this.rc = true;\\n    this.richChange = data.richChange || [];\\n    this.richChangeEx = data.richChangeEx || [];\\n    this.richValue = data.richValue || [];\\n    this.selEnd = data.selEnd ?? -1;\\n    this.selStart = data.selStart ?? -1;\\n    this.shift = data.shift || false;\\n    this.source = data.source || null;\\n    this.target = data.target || null;\\n    this.targetName = \\\"\\\";\\n    this.type = \\\"Field\\\";\\n    this.value = data.value || \\\"\\\";\\n    this.willCommit = data.willCommit || false;\\n  }\\n}\\nclass EventDispatcher {\\n  constructor(document, calculationOrder, objects, externalCall) {\\n    this._document = document;\\n    this._calculationOrder = calculationOrder;\\n    this._objects = objects;\\n    this._externalCall = externalCall;\\n    this._document.obj._eventDispatcher = this;\\n    this._isCalculating = false;\\n  }\\n  mergeChange(event) {\\n    let value = event.value;\\n    if (Array.isArray(value)) {\\n      return value;\\n    }\\n    if (typeof value !== \\\"string\\\") {\\n      value = value.toString();\\n    }\\n    const prefix = event.selStart >= 0 ? value.substring(0, event.selStart) : \\\"\\\";\\n    const postfix = event.selEnd >= 0 && event.selEnd <= value.length ? value.substring(event.selEnd) : \\\"\\\";\\n    return `${prefix}${event.change}${postfix}`;\\n  }\\n  userActivation() {\\n    this._document.obj._userActivation = true;\\n    this._externalCall(\\\"setTimeout\\\", [USERACTIVATION_CALLBACKID, USERACTIVATION_MAXTIME_VALIDITY]);\\n  }\\n  dispatch(baseEvent) {\\n    const id = baseEvent.id;\\n    if (!(id in this._objects)) {\\n      let event;\\n      if (id === \\\"doc\\\" || id === \\\"page\\\") {\\n        event = globalThis.event = new Event(baseEvent);\\n        event.source = event.target = this._document.wrapped;\\n        event.name = baseEvent.name;\\n      }\\n      if (id === \\\"doc\\\") {\\n        const eventName = event.name;\\n        if (eventName === \\\"Open\\\") {\\n          this.userActivation();\\n          this._document.obj._initActions();\\n          this.formatAll();\\n        }\\n        if (![\\\"DidPrint\\\", \\\"DidSave\\\", \\\"WillPrint\\\", \\\"WillSave\\\"].includes(eventName)) {\\n          this.userActivation();\\n        }\\n        this._document.obj._dispatchDocEvent(event.name);\\n      } else if (id === \\\"page\\\") {\\n        this.userActivation();\\n        this._document.obj._dispatchPageEvent(event.name, baseEvent.actions, baseEvent.pageNumber);\\n      } else if (id === \\\"app\\\" && baseEvent.name === \\\"ResetForm\\\") {\\n        this.userActivation();\\n        for (const fieldId of baseEvent.ids) {\\n          const obj = this._objects[fieldId];\\n          obj?.obj._reset();\\n        }\\n      }\\n      return;\\n    }\\n    const name = baseEvent.name;\\n    const source = this._objects[id];\\n    const event = globalThis.event = new Event(baseEvent);\\n    let savedChange;\\n    this.userActivation();\\n    if (source.obj._isButton()) {\\n      source.obj._id = id;\\n      event.value = source.obj._getExportValue(event.value);\\n      if (name === \\\"Action\\\") {\\n        source.obj._value = event.value;\\n      }\\n    }\\n    switch (name) {\\n      case \\\"Keystroke\\\":\\n        savedChange = {\\n          value: event.value,\\n          changeEx: event.changeEx,\\n          change: event.change,\\n          selStart: event.selStart,\\n          selEnd: event.selEnd\\n        };\\n        break;\\n      case \\\"Blur\\\":\\n      case \\\"Focus\\\":\\n        Object.defineProperty(event, \\\"value\\\", {\\n          configurable: false,\\n          writable: false,\\n          enumerable: true,\\n          value: event.value\\n        });\\n        break;\\n      case \\\"Validate\\\":\\n        this.runValidation(source, event);\\n        return;\\n      case \\\"Action\\\":\\n        this.runActions(source, source, event, name);\\n        this.runCalculate(source, event);\\n        return;\\n    }\\n    this.runActions(source, source, event, name);\\n    if (name !== \\\"Keystroke\\\") {\\n      return;\\n    }\\n    if (event.rc) {\\n      if (event.willCommit) {\\n        this.runValidation(source, event);\\n      } else {\\n        if (source.obj._isChoice) {\\n          source.obj.value = savedChange.changeEx;\\n          source.obj._send({\\n            id: source.obj._id,\\n            siblings: source.obj._siblings,\\n            value: source.obj.value\\n          });\\n          return;\\n        }\\n        const value = source.obj.value = this.mergeChange(event);\\n        let selStart, selEnd;\\n        if (event.selStart !== savedChange.selStart || event.selEnd !== savedChange.selEnd) {\\n          selStart = event.selStart;\\n          selEnd = event.selEnd;\\n        } else {\\n          selEnd = selStart = savedChange.selStart + event.change.length;\\n        }\\n        source.obj._send({\\n          id: source.obj._id,\\n          siblings: source.obj._siblings,\\n          value,\\n          selRange: [selStart, selEnd]\\n        });\\n      }\\n    } else if (!event.willCommit) {\\n      source.obj._send({\\n        id: source.obj._id,\\n        siblings: source.obj._siblings,\\n        value: savedChange.value,\\n        selRange: [savedChange.selStart, savedChange.selEnd]\\n      });\\n    } else {\\n      source.obj._send({\\n        id: source.obj._id,\\n        siblings: source.obj._siblings,\\n        value: \\\"\\\",\\n        formattedValue: null,\\n        selRange: [0, 0]\\n      });\\n    }\\n  }\\n  formatAll() {\\n    const event = globalThis.event = new Event({});\\n    for (const source of Object.values(this._objects)) {\\n      event.value = source.obj.value;\\n      this.runActions(source, source, event, \\\"Format\\\");\\n    }\\n  }\\n  runValidation(source, event) {\\n    const didValidateRun = this.runActions(source, source, event, \\\"Validate\\\");\\n    if (event.rc) {\\n      source.obj.value = event.value;\\n      this.runCalculate(source, event);\\n      const savedValue = source.obj._getValue();\\n      event.value = source.obj.value;\\n      let formattedValue = null;\\n      if (this.runActions(source, source, event, \\\"Format\\\")) {\\n        formattedValue = event.value?.toString?.();\\n      }\\n      source.obj._send({\\n        id: source.obj._id,\\n        siblings: source.obj._siblings,\\n        value: savedValue,\\n        formattedValue\\n      });\\n      event.value = savedValue;\\n    } else if (didValidateRun) {\\n      source.obj._send({\\n        id: source.obj._id,\\n        siblings: source.obj._siblings,\\n        value: \\\"\\\",\\n        formattedValue: null,\\n        selRange: [0, 0],\\n        focus: true\\n      });\\n    }\\n  }\\n  runActions(source, target, event, eventName) {\\n    event.source = source.wrapped;\\n    event.target = target.wrapped;\\n    event.name = eventName;\\n    event.targetName = target.obj.name;\\n    event.rc = true;\\n    return target.obj._runActions(event);\\n  }\\n  calculateNow() {\\n    if (!this._calculationOrder || this._isCalculating || !this._document.obj.calculate) {\\n      return;\\n    }\\n    this._isCalculating = true;\\n    const first = this._calculationOrder[0];\\n    const source = this._objects[first];\\n    globalThis.event = new Event({});\\n    try {\\n      this.runCalculate(source, globalThis.event);\\n    } catch (error) {\\n      this._isCalculating = false;\\n      throw error;\\n    }\\n    this._isCalculating = false;\\n  }\\n  runCalculate(source, event) {\\n    if (!this._calculationOrder || !this._document.obj.calculate) {\\n      return;\\n    }\\n    for (const targetId of this._calculationOrder) {\\n      if (!(targetId in this._objects)) {\\n        continue;\\n      }\\n      if (!this._document.obj.calculate) {\\n        break;\\n      }\\n      event.value = null;\\n      const target = this._objects[targetId];\\n      let savedValue = target.obj._getValue();\\n      this.runActions(source, target, event, \\\"Calculate\\\");\\n      if (!event.rc) {\\n        continue;\\n      }\\n      if (event.value !== null) {\\n        target.obj.value = event.value;\\n      } else {\\n        event.value = target.obj._getValue();\\n      }\\n      this.runActions(target, target, event, \\\"Validate\\\");\\n      if (!event.rc) {\\n        if (target.obj._getValue() !== savedValue) {\\n          target.wrapped.value = savedValue;\\n        }\\n        continue;\\n      }\\n      if (event.value === null) {\\n        event.value = target.obj._getValue();\\n      }\\n      savedValue = target.obj._getValue();\\n      let formattedValue = null;\\n      if (this.runActions(target, target, event, \\\"Format\\\")) {\\n        formattedValue = event.value?.toString?.();\\n      }\\n      target.obj._send({\\n        id: target.obj._id,\\n        siblings: target.obj._siblings,\\n        value: savedValue,\\n        formattedValue\\n      });\\n    }\\n  }\\n}\\n\\n;// ./src/scripting_api/fullscreen.js\\n\\n\\nclass FullScreen extends PDFObject {\\n  constructor(data) {\\n    super(data);\\n    this._backgroundColor = [];\\n    this._clickAdvances = true;\\n    this._cursor = Cursor.hidden;\\n    this._defaultTransition = \\\"\\\";\\n    this._escapeExits = true;\\n    this._isFullScreen = true;\\n    this._loop = false;\\n    this._timeDelay = 3600;\\n    this._usePageTiming = false;\\n    this._useTimer = false;\\n  }\\n  get backgroundColor() {\\n    return this._backgroundColor;\\n  }\\n  set backgroundColor(_) {}\\n  get clickAdvances() {\\n    return this._clickAdvances;\\n  }\\n  set clickAdvances(_) {}\\n  get cursor() {\\n    return this._cursor;\\n  }\\n  set cursor(_) {}\\n  get defaultTransition() {\\n    return this._defaultTransition;\\n  }\\n  set defaultTransition(_) {}\\n  get escapeExits() {\\n    return this._escapeExits;\\n  }\\n  set escapeExits(_) {}\\n  get isFullScreen() {\\n    return this._isFullScreen;\\n  }\\n  set isFullScreen(_) {}\\n  get loop() {\\n    return this._loop;\\n  }\\n  set loop(_) {}\\n  get timeDelay() {\\n    return this._timeDelay;\\n  }\\n  set timeDelay(_) {}\\n  get transitions() {\\n    return [\\\"Replace\\\", \\\"WipeRight\\\", \\\"WipeLeft\\\", \\\"WipeDown\\\", \\\"WipeUp\\\", \\\"SplitHorizontalIn\\\", \\\"SplitHorizontalOut\\\", \\\"SplitVerticalIn\\\", \\\"SplitVerticalOut\\\", \\\"BlindsHorizontal\\\", \\\"BlindsVertical\\\", \\\"BoxIn\\\", \\\"BoxOut\\\", \\\"GlitterRight\\\", \\\"GlitterDown\\\", \\\"GlitterRightDown\\\", \\\"Dissolve\\\", \\\"Random\\\"];\\n  }\\n  set transitions(_) {\\n    throw new Error(\\\"fullscreen.transitions is read-only\\\");\\n  }\\n  get usePageTiming() {\\n    return this._usePageTiming;\\n  }\\n  set usePageTiming(_) {}\\n  get useTimer() {\\n    return this._useTimer;\\n  }\\n  set useTimer(_) {}\\n}\\n\\n;// ./src/scripting_api/thermometer.js\\n\\nclass Thermometer extends PDFObject {\\n  constructor(data) {\\n    super(data);\\n    this._cancelled = false;\\n    this._duration = 100;\\n    this._text = \\\"\\\";\\n    this._value = 0;\\n  }\\n  get cancelled() {\\n    return this._cancelled;\\n  }\\n  set cancelled(_) {\\n    throw new Error(\\\"thermometer.cancelled is read-only\\\");\\n  }\\n  get duration() {\\n    return this._duration;\\n  }\\n  set duration(val) {\\n    this._duration = val;\\n  }\\n  get text() {\\n    return this._text;\\n  }\\n  set text(val) {\\n    this._text = val;\\n  }\\n  get value() {\\n    return this._value;\\n  }\\n  set value(val) {\\n    this._value = val;\\n  }\\n  begin() {}\\n  end() {}\\n}\\n\\n;// ./src/scripting_api/app.js\\n\\n\\n\\n\\n\\n\\nclass App extends PDFObject {\\n  constructor(data) {\\n    super(data);\\n    this._constants = null;\\n    this._focusRect = true;\\n    this._fs = null;\\n    this._language = App._getLanguage(data.language);\\n    this._openInPlace = false;\\n    this._platform = App._getPlatform(data.platform);\\n    this._runtimeHighlight = false;\\n    this._runtimeHighlightColor = [\\\"T\\\"];\\n    this._thermometer = null;\\n    this._toolbar = false;\\n    this._document = data._document;\\n    this._proxyHandler = data.proxyHandler;\\n    this._objects = Object.create(null);\\n    this._eventDispatcher = new EventDispatcher(this._document, data.calculationOrder, this._objects, data.externalCall);\\n    this._timeoutIds = new WeakMap();\\n    if (typeof FinalizationRegistry !== \\\"undefined\\\") {\\n      this._timeoutIdsRegistry = new FinalizationRegistry(this._cleanTimeout.bind(this));\\n    } else {\\n      this._timeoutIdsRegistry = null;\\n    }\\n    this._timeoutCallbackIds = new Map();\\n    this._timeoutCallbackId = USERACTIVATION_CALLBACKID + 1;\\n    this._globalEval = data.globalEval;\\n    this._externalCall = data.externalCall;\\n  }\\n  _dispatchEvent(pdfEvent) {\\n    this._eventDispatcher.dispatch(pdfEvent);\\n  }\\n  _registerTimeoutCallback(cExpr) {\\n    const id = this._timeoutCallbackId++;\\n    this._timeoutCallbackIds.set(id, cExpr);\\n    return id;\\n  }\\n  _unregisterTimeoutCallback(id) {\\n    this._timeoutCallbackIds.delete(id);\\n  }\\n  _evalCallback({\\n    callbackId,\\n    interval\\n  }) {\\n    if (callbackId === USERACTIVATION_CALLBACKID) {\\n      this._document.obj._userActivation = false;\\n      return;\\n    }\\n    const expr = this._timeoutCallbackIds.get(callbackId);\\n    if (!interval) {\\n      this._unregisterTimeoutCallback(callbackId);\\n    }\\n    if (expr) {\\n      this._globalEval(expr);\\n    }\\n  }\\n  _registerTimeout(callbackId, interval) {\\n    const timeout = Object.create(null);\\n    const id = {\\n      callbackId,\\n      interval\\n    };\\n    this._timeoutIds.set(timeout, id);\\n    this._timeoutIdsRegistry?.register(timeout, id);\\n    return timeout;\\n  }\\n  _unregisterTimeout(timeout) {\\n    this._timeoutIdsRegistry?.unregister(timeout);\\n    const data = this._timeoutIds.get(timeout);\\n    if (!data) {\\n      return;\\n    }\\n    this._timeoutIds.delete(timeout);\\n    this._cleanTimeout(data);\\n  }\\n  _cleanTimeout({\\n    callbackId,\\n    interval\\n  }) {\\n    this._unregisterTimeoutCallback(callbackId);\\n    if (interval) {\\n      this._externalCall(\\\"clearInterval\\\", [callbackId]);\\n    } else {\\n      this._externalCall(\\\"clearTimeout\\\", [callbackId]);\\n    }\\n  }\\n  static _getPlatform(platform) {\\n    if (typeof platform === \\\"string\\\") {\\n      platform = platform.toLowerCase();\\n      if (platform.includes(\\\"win\\\")) {\\n        return \\\"WIN\\\";\\n      } else if (platform.includes(\\\"mac\\\")) {\\n        return \\\"MAC\\\";\\n      }\\n    }\\n    return \\\"UNIX\\\";\\n  }\\n  static _getLanguage(language) {\\n    const [main, sub] = language.toLowerCase().split(/[-_]/);\\n    switch (main) {\\n      case \\\"zh\\\":\\n        if (sub === \\\"cn\\\" || sub === \\\"sg\\\") {\\n          return \\\"CHS\\\";\\n        }\\n        return \\\"CHT\\\";\\n      case \\\"da\\\":\\n        return \\\"DAN\\\";\\n      case \\\"de\\\":\\n        return \\\"DEU\\\";\\n      case \\\"es\\\":\\n        return \\\"ESP\\\";\\n      case \\\"fr\\\":\\n        return \\\"FRA\\\";\\n      case \\\"it\\\":\\n        return \\\"ITA\\\";\\n      case \\\"ko\\\":\\n        return \\\"KOR\\\";\\n      case \\\"ja\\\":\\n        return \\\"JPN\\\";\\n      case \\\"nl\\\":\\n        return \\\"NLD\\\";\\n      case \\\"no\\\":\\n        return \\\"NOR\\\";\\n      case \\\"pt\\\":\\n        if (sub === \\\"br\\\") {\\n          return \\\"PTB\\\";\\n        }\\n        return \\\"ENU\\\";\\n      case \\\"fi\\\":\\n        return \\\"SUO\\\";\\n      case \\\"SV\\\":\\n        return \\\"SVE\\\";\\n      default:\\n        return \\\"ENU\\\";\\n    }\\n  }\\n  get activeDocs() {\\n    return [this._document.wrapped];\\n  }\\n  set activeDocs(_) {\\n    throw new Error(\\\"app.activeDocs is read-only\\\");\\n  }\\n  get calculate() {\\n    return this._document.obj.calculate;\\n  }\\n  set calculate(calculate) {\\n    this._document.obj.calculate = calculate;\\n  }\\n  get constants() {\\n    if (!this._constants) {\\n      this._constants = Object.freeze({\\n        align: Object.freeze({\\n          left: 0,\\n          center: 1,\\n          right: 2,\\n          top: 3,\\n          bottom: 4\\n        })\\n      });\\n    }\\n    return this._constants;\\n  }\\n  set constants(_) {\\n    throw new Error(\\\"app.constants is read-only\\\");\\n  }\\n  get focusRect() {\\n    return this._focusRect;\\n  }\\n  set focusRect(val) {\\n    this._focusRect = val;\\n  }\\n  get formsVersion() {\\n    return FORMS_VERSION;\\n  }\\n  set formsVersion(_) {\\n    throw new Error(\\\"app.formsVersion is read-only\\\");\\n  }\\n  get fromPDFConverters() {\\n    return [];\\n  }\\n  set fromPDFConverters(_) {\\n    throw new Error(\\\"app.fromPDFConverters is read-only\\\");\\n  }\\n  get fs() {\\n    if (this._fs === null) {\\n      this._fs = new Proxy(new FullScreen({\\n        send: this._send\\n      }), this._proxyHandler);\\n    }\\n    return this._fs;\\n  }\\n  set fs(_) {\\n    throw new Error(\\\"app.fs is read-only\\\");\\n  }\\n  get language() {\\n    return this._language;\\n  }\\n  set language(_) {\\n    throw new Error(\\\"app.language is read-only\\\");\\n  }\\n  get media() {\\n    return undefined;\\n  }\\n  set media(_) {\\n    throw new Error(\\\"app.media is read-only\\\");\\n  }\\n  get monitors() {\\n    return [];\\n  }\\n  set monitors(_) {\\n    throw new Error(\\\"app.monitors is read-only\\\");\\n  }\\n  get numPlugins() {\\n    return 0;\\n  }\\n  set numPlugins(_) {\\n    throw new Error(\\\"app.numPlugins is read-only\\\");\\n  }\\n  get openInPlace() {\\n    return this._openInPlace;\\n  }\\n  set openInPlace(val) {\\n    this._openInPlace = val;\\n  }\\n  get platform() {\\n    return this._platform;\\n  }\\n  set platform(_) {\\n    throw new Error(\\\"app.platform is read-only\\\");\\n  }\\n  get plugins() {\\n    return [];\\n  }\\n  set plugins(_) {\\n    throw new Error(\\\"app.plugins is read-only\\\");\\n  }\\n  get printColorProfiles() {\\n    return [];\\n  }\\n  set printColorProfiles(_) {\\n    throw new Error(\\\"app.printColorProfiles is read-only\\\");\\n  }\\n  get printerNames() {\\n    return [];\\n  }\\n  set printerNames(_) {\\n    throw new Error(\\\"app.printerNames is read-only\\\");\\n  }\\n  get runtimeHighlight() {\\n    return this._runtimeHighlight;\\n  }\\n  set runtimeHighlight(val) {\\n    this._runtimeHighlight = val;\\n  }\\n  get runtimeHighlightColor() {\\n    return this._runtimeHighlightColor;\\n  }\\n  set runtimeHighlightColor(val) {\\n    if (Color._isValidColor(val)) {\\n      this._runtimeHighlightColor = val;\\n    }\\n  }\\n  get thermometer() {\\n    if (this._thermometer === null) {\\n      this._thermometer = new Proxy(new Thermometer({\\n        send: this._send\\n      }), this._proxyHandler);\\n    }\\n    return this._thermometer;\\n  }\\n  set thermometer(_) {\\n    throw new Error(\\\"app.thermometer is read-only\\\");\\n  }\\n  get toolbar() {\\n    return this._toolbar;\\n  }\\n  set toolbar(val) {\\n    this._toolbar = val;\\n  }\\n  get toolbarHorizontal() {\\n    return this.toolbar;\\n  }\\n  set toolbarHorizontal(value) {\\n    this.toolbar = value;\\n  }\\n  get toolbarVertical() {\\n    return this.toolbar;\\n  }\\n  set toolbarVertical(value) {\\n    this.toolbar = value;\\n  }\\n  get viewerType() {\\n    return VIEWER_TYPE;\\n  }\\n  set viewerType(_) {\\n    throw new Error(\\\"app.viewerType is read-only\\\");\\n  }\\n  get viewerVariation() {\\n    return VIEWER_VARIATION;\\n  }\\n  set viewerVariation(_) {\\n    throw new Error(\\\"app.viewerVariation is read-only\\\");\\n  }\\n  get viewerVersion() {\\n    return VIEWER_VERSION;\\n  }\\n  set viewerVersion(_) {\\n    throw new Error(\\\"app.viewerVersion is read-only\\\");\\n  }\\n  addMenuItem() {}\\n  addSubMenu() {}\\n  addToolButton() {}\\n  alert(cMsg, nIcon = 0, nType = 0, cTitle = \\\"PDF.js\\\", oDoc = null, oCheckbox = null) {\\n    if (!this._document.obj._userActivation) {\\n      return 0;\\n    }\\n    this._document.obj._userActivation = false;\\n    if (cMsg && typeof cMsg === \\\"object\\\") {\\n      nType = cMsg.nType;\\n      cMsg = cMsg.cMsg;\\n    }\\n    cMsg = (cMsg || \\\"\\\").toString();\\n    nType = typeof nType !== \\\"number\\\" || isNaN(nType) || nType < 0 || nType > 3 ? 0 : nType;\\n    if (nType >= 2) {\\n      return this._externalCall(\\\"confirm\\\", [cMsg]) ? 4 : 3;\\n    }\\n    this._externalCall(\\\"alert\\\", [cMsg]);\\n    return 1;\\n  }\\n  beep() {}\\n  beginPriv() {}\\n  browseForDoc() {}\\n  clearInterval(oInterval) {\\n    this._unregisterTimeout(oInterval);\\n  }\\n  clearTimeOut(oTime) {\\n    this._unregisterTimeout(oTime);\\n  }\\n  endPriv() {}\\n  execDialog() {}\\n  execMenuItem(item) {\\n    if (!this._document.obj._userActivation) {\\n      return;\\n    }\\n    this._document.obj._userActivation = false;\\n    switch (item) {\\n      case \\\"SaveAs\\\":\\n        if (this._document.obj._disableSaving) {\\n          return;\\n        }\\n        this._send({\\n          command: item\\n        });\\n        break;\\n      case \\\"FirstPage\\\":\\n      case \\\"LastPage\\\":\\n      case \\\"NextPage\\\":\\n      case \\\"PrevPage\\\":\\n      case \\\"ZoomViewIn\\\":\\n      case \\\"ZoomViewOut\\\":\\n        this._send({\\n          command: item\\n        });\\n        break;\\n      case \\\"FitPage\\\":\\n        this._send({\\n          command: \\\"zoom\\\",\\n          value: \\\"page-fit\\\"\\n        });\\n        break;\\n      case \\\"Print\\\":\\n        if (this._document.obj._disablePrinting) {\\n          return;\\n        }\\n        this._send({\\n          command: \\\"print\\\"\\n        });\\n        break;\\n    }\\n  }\\n  getNthPlugInName() {}\\n  getPath() {}\\n  goBack() {}\\n  goForward() {}\\n  hideMenuItem() {}\\n  hideToolbarButton() {}\\n  launchURL() {}\\n  listMenuItems() {}\\n  listToolbarButtons() {}\\n  loadPolicyFile() {}\\n  mailGetAddrs() {}\\n  mailMsg() {}\\n  newDoc() {}\\n  newCollection() {}\\n  newFDF() {}\\n  openDoc() {}\\n  openFDF() {}\\n  popUpMenu() {}\\n  popUpMenuEx() {}\\n  removeToolButton() {}\\n  response(cQuestion, cTitle = \\\"\\\", cDefault = \\\"\\\", bPassword = \\\"\\\", cLabel = \\\"\\\") {\\n    if (cQuestion && typeof cQuestion === \\\"object\\\") {\\n      cDefault = cQuestion.cDefault;\\n      cQuestion = cQuestion.cQuestion;\\n    }\\n    cQuestion = (cQuestion || \\\"\\\").toString();\\n    cDefault = (cDefault || \\\"\\\").toString();\\n    return this._externalCall(\\\"prompt\\\", [cQuestion, cDefault || \\\"\\\"]);\\n  }\\n  setInterval(cExpr, nMilliseconds = 0) {\\n    if (cExpr && typeof cExpr === \\\"object\\\") {\\n      nMilliseconds = cExpr.nMilliseconds || 0;\\n      cExpr = cExpr.cExpr;\\n    }\\n    if (typeof cExpr !== \\\"string\\\") {\\n      throw new TypeError(\\\"First argument of app.setInterval must be a string\\\");\\n    }\\n    if (typeof nMilliseconds !== \\\"number\\\") {\\n      throw new TypeError(\\\"Second argument of app.setInterval must be a number\\\");\\n    }\\n    const callbackId = this._registerTimeoutCallback(cExpr);\\n    this._externalCall(\\\"setInterval\\\", [callbackId, nMilliseconds]);\\n    return this._registerTimeout(callbackId, true);\\n  }\\n  setTimeOut(cExpr, nMilliseconds = 0) {\\n    if (cExpr && typeof cExpr === \\\"object\\\") {\\n      nMilliseconds = cExpr.nMilliseconds || 0;\\n      cExpr = cExpr.cExpr;\\n    }\\n    if (typeof cExpr !== \\\"string\\\") {\\n      throw new TypeError(\\\"First argument of app.setTimeOut must be a string\\\");\\n    }\\n    if (typeof nMilliseconds !== \\\"number\\\") {\\n      throw new TypeError(\\\"Second argument of app.setTimeOut must be a number\\\");\\n    }\\n    const callbackId = this._registerTimeoutCallback(cExpr);\\n    this._externalCall(\\\"setTimeout\\\", [callbackId, nMilliseconds]);\\n    return this._registerTimeout(callbackId, false);\\n  }\\n  trustedFunction() {}\\n  trustPropagatorFunction() {}\\n}\\n\\n;// ./src/scripting_api/console.js\\n\\nclass Console extends PDFObject {\\n  clear() {\\n    this._send({\\n      id: \\\"clear\\\"\\n    });\\n  }\\n  hide() {}\\n  println(msg) {\\n    if (typeof msg === \\\"string\\\") {\\n      this._send({\\n        command: \\\"println\\\",\\n        value: \\\"PDF.js Console:: \\\" + msg\\n      });\\n    }\\n  }\\n  show() {}\\n}\\n\\n;// ./src/scripting_api/print_params.js\\nclass PrintParams {\\n  constructor(data) {\\n    this.binaryOk = true;\\n    this.bitmapDPI = 150;\\n    this.booklet = {\\n      binding: 0,\\n      duplexMode: 0,\\n      subsetFrom: 0,\\n      subsetTo: -1\\n    };\\n    this.colorOverride = 0;\\n    this.colorProfile = \\\"\\\";\\n    this.constants = Object.freeze({\\n      bookletBindings: Object.freeze({\\n        Left: 0,\\n        Right: 1,\\n        LeftTall: 2,\\n        RightTall: 3\\n      }),\\n      bookletDuplexMode: Object.freeze({\\n        BothSides: 0,\\n        FrontSideOnly: 1,\\n        BasicSideOnly: 2\\n      }),\\n      colorOverrides: Object.freeze({\\n        auto: 0,\\n        gray: 1,\\n        mono: 2\\n      }),\\n      fontPolicies: Object.freeze({\\n        everyPage: 0,\\n        jobStart: 1,\\n        pageRange: 2\\n      }),\\n      handling: Object.freeze({\\n        none: 0,\\n        fit: 1,\\n        shrink: 2,\\n        tileAll: 3,\\n        tileLarge: 4,\\n        nUp: 5,\\n        booklet: 6\\n      }),\\n      interactionLevel: Object.freeze({\\n        automatic: 0,\\n        full: 1,\\n        silent: 2\\n      }),\\n      nUpPageOrders: Object.freeze({\\n        Horizontal: 0,\\n        HorizontalReversed: 1,\\n        Vertical: 2\\n      }),\\n      printContents: Object.freeze({\\n        doc: 0,\\n        docAndComments: 1,\\n        formFieldsOnly: 2\\n      }),\\n      flagValues: Object.freeze({\\n        applyOverPrint: 1,\\n        applySoftProofSettings: 1 << 1,\\n        applyWorkingColorSpaces: 1 << 2,\\n        emitHalftones: 1 << 3,\\n        emitPostScriptXObjects: 1 << 4,\\n        emitFormsAsPSForms: 1 << 5,\\n        maxJP2KRes: 1 << 6,\\n        setPageSize: 1 << 7,\\n        suppressBG: 1 << 8,\\n        suppressCenter: 1 << 9,\\n        suppressCJKFontSubst: 1 << 10,\\n        suppressCropClip: 1 << 1,\\n        suppressRotate: 1 << 12,\\n        suppressTransfer: 1 << 13,\\n        suppressUCR: 1 << 14,\\n        useTrapAnnots: 1 << 15,\\n        usePrintersMarks: 1 << 16\\n      }),\\n      rasterFlagValues: Object.freeze({\\n        textToOutline: 1,\\n        strokesToOutline: 1 << 1,\\n        allowComplexClip: 1 << 2,\\n        preserveOverprint: 1 << 3\\n      }),\\n      subsets: Object.freeze({\\n        all: 0,\\n        even: 1,\\n        odd: 2\\n      }),\\n      tileMarks: Object.freeze({\\n        none: 0,\\n        west: 1,\\n        east: 2\\n      }),\\n      usages: Object.freeze({\\n        auto: 0,\\n        use: 1,\\n        noUse: 2\\n      })\\n    });\\n    this.downloadFarEastFonts = false;\\n    this.fileName = \\\"\\\";\\n    this.firstPage = 0;\\n    this.flags = 0;\\n    this.fontPolicy = 0;\\n    this.gradientDPI = 150;\\n    this.interactive = 1;\\n    this.lastPage = data.lastPage;\\n    this.npUpAutoRotate = false;\\n    this.npUpNumPagesH = 2;\\n    this.npUpNumPagesV = 2;\\n    this.npUpPageBorder = false;\\n    this.npUpPageOrder = 0;\\n    this.pageHandling = 0;\\n    this.pageSubset = 0;\\n    this.printAsImage = false;\\n    this.printContent = 0;\\n    this.printerName = \\\"\\\";\\n    this.psLevel = 0;\\n    this.rasterFlags = 0;\\n    this.reversePages = false;\\n    this.tileLabel = false;\\n    this.tileMark = 0;\\n    this.tileOverlap = 0;\\n    this.tileScale = 1.0;\\n    this.transparencyLevel = 75;\\n    this.usePrinterCRD = 0;\\n    this.useT1Conversion = 0;\\n  }\\n}\\n\\n;// ./src/scripting_api/doc.js\\n\\n\\n\\n\\n\\nconst DOC_EXTERNAL = false;\\nclass InfoProxyHandler {\\n  static get(obj, prop) {\\n    return obj[prop.toLowerCase()];\\n  }\\n  static set(obj, prop, value) {\\n    throw new Error(`doc.info.${prop} is read-only`);\\n  }\\n}\\nclass Doc extends PDFObject {\\n  constructor(data) {\\n    super(data);\\n    this._expandos = globalThis;\\n    this._baseURL = data.baseURL || \\\"\\\";\\n    this._calculate = true;\\n    this._delay = false;\\n    this._dirty = false;\\n    this._disclosed = false;\\n    this._media = undefined;\\n    this._metadata = data.metadata || \\\"\\\";\\n    this._noautocomplete = undefined;\\n    this._nocache = undefined;\\n    this._spellDictionaryOrder = [];\\n    this._spellLanguageOrder = [];\\n    this._printParams = null;\\n    this._fields = new Map();\\n    this._fieldNames = [];\\n    this._event = null;\\n    this._author = data.Author || \\\"\\\";\\n    this._creator = data.Creator || \\\"\\\";\\n    this._creationDate = this._getDate(data.CreationDate) || null;\\n    this._docID = data.docID || [\\\"\\\", \\\"\\\"];\\n    this._documentFileName = data.filename || \\\"\\\";\\n    this._filesize = data.filesize || 0;\\n    this._keywords = data.Keywords || \\\"\\\";\\n    this._layout = data.layout || \\\"\\\";\\n    this._modDate = this._getDate(data.ModDate) || null;\\n    this._numFields = 0;\\n    this._numPages = data.numPages || 1;\\n    this._pageNum = data.pageNum || 0;\\n    this._producer = data.Producer || \\\"\\\";\\n    this._securityHandler = data.EncryptFilterName || null;\\n    this._subject = data.Subject || \\\"\\\";\\n    this._title = data.Title || \\\"\\\";\\n    this._URL = data.URL || \\\"\\\";\\n    this._info = new Proxy({\\n      title: this._title,\\n      author: this._author,\\n      authors: data.authors || [this._author],\\n      subject: this._subject,\\n      keywords: this._keywords,\\n      creator: this._creator,\\n      producer: this._producer,\\n      creationdate: this._creationDate,\\n      moddate: this._modDate,\\n      trapped: data.Trapped || \\\"Unknown\\\"\\n    }, InfoProxyHandler);\\n    this._zoomType = ZoomType.none;\\n    this._zoom = data.zoom || 100;\\n    this._actions = createActionsMap(data.actions);\\n    this._globalEval = data.globalEval;\\n    this._pageActions = new Map();\\n    this._userActivation = false;\\n    this._disablePrinting = false;\\n    this._disableSaving = false;\\n  }\\n  _initActions() {\\n    const dontRun = new Set([\\\"WillClose\\\", \\\"WillSave\\\", \\\"DidSave\\\", \\\"WillPrint\\\", \\\"DidPrint\\\", \\\"OpenAction\\\"]);\\n    this._disableSaving = true;\\n    for (const actionName of this._actions.keys()) {\\n      if (!dontRun.has(actionName)) {\\n        this._runActions(actionName);\\n      }\\n    }\\n    this._runActions(\\\"OpenAction\\\");\\n    this._disableSaving = false;\\n  }\\n  _dispatchDocEvent(name) {\\n    switch (name) {\\n      case \\\"Open\\\":\\n        this._disableSaving = true;\\n        this._runActions(\\\"OpenAction\\\");\\n        this._disableSaving = false;\\n        break;\\n      case \\\"WillPrint\\\":\\n        this._disablePrinting = true;\\n        try {\\n          this._runActions(name);\\n        } catch (error) {\\n          this._send(serializeError(error));\\n        }\\n        this._send({\\n          command: \\\"WillPrintFinished\\\"\\n        });\\n        this._disablePrinting = false;\\n        break;\\n      case \\\"WillSave\\\":\\n        this._disableSaving = true;\\n        this._runActions(name);\\n        this._disableSaving = false;\\n        break;\\n      default:\\n        this._runActions(name);\\n    }\\n  }\\n  _dispatchPageEvent(name, actions, pageNumber) {\\n    if (name === \\\"PageOpen\\\") {\\n      if (!this._pageActions.has(pageNumber)) {\\n        this._pageActions.set(pageNumber, createActionsMap(actions));\\n      }\\n      this._pageNum = pageNumber - 1;\\n    }\\n    actions = this._pageActions.get(pageNumber)?.get(name);\\n    if (actions) {\\n      for (const action of actions) {\\n        this._globalEval(action);\\n      }\\n    }\\n  }\\n  _runActions(name) {\\n    const actions = this._actions.get(name);\\n    if (actions) {\\n      for (const action of actions) {\\n        this._globalEval(action);\\n      }\\n    }\\n  }\\n  _addField(name, field) {\\n    this._fields.set(name, field);\\n    this._fieldNames.push(name);\\n    this._numFields++;\\n  }\\n  _getDate(date) {\\n    if (!date || date.length < 15 || !date.startsWith(\\\"D:\\\")) {\\n      return date;\\n    }\\n    date = date.substring(2);\\n    const year = date.substring(0, 4);\\n    const month = date.substring(4, 6);\\n    const day = date.substring(6, 8);\\n    const hour = date.substring(8, 10);\\n    const minute = date.substring(10, 12);\\n    const o = date.charAt(12);\\n    let second, offsetPos;\\n    if (o === \\\"Z\\\" || o === \\\"+\\\" || o === \\\"-\\\") {\\n      second = \\\"00\\\";\\n      offsetPos = 12;\\n    } else {\\n      second = date.substring(12, 14);\\n      offsetPos = 14;\\n    }\\n    const offset = date.substring(offsetPos).replaceAll(\\\"'\\\", \\\"\\\");\\n    return new Date(`${year}-${month}-${day}T${hour}:${minute}:${second}${offset}`);\\n  }\\n  get author() {\\n    return this._author;\\n  }\\n  set author(_) {\\n    throw new Error(\\\"doc.author is read-only\\\");\\n  }\\n  get baseURL() {\\n    return this._baseURL;\\n  }\\n  set baseURL(baseURL) {\\n    this._baseURL = baseURL;\\n  }\\n  get bookmarkRoot() {\\n    return undefined;\\n  }\\n  set bookmarkRoot(_) {\\n    throw new Error(\\\"doc.bookmarkRoot is read-only\\\");\\n  }\\n  get calculate() {\\n    return this._calculate;\\n  }\\n  set calculate(calculate) {\\n    this._calculate = calculate;\\n  }\\n  get creator() {\\n    return this._creator;\\n  }\\n  set creator(_) {\\n    throw new Error(\\\"doc.creator is read-only\\\");\\n  }\\n  get dataObjects() {\\n    return [];\\n  }\\n  set dataObjects(_) {\\n    throw new Error(\\\"doc.dataObjects is read-only\\\");\\n  }\\n  get delay() {\\n    return this._delay;\\n  }\\n  set delay(delay) {\\n    this._delay = delay;\\n  }\\n  get dirty() {\\n    return this._dirty;\\n  }\\n  set dirty(dirty) {\\n    this._dirty = dirty;\\n  }\\n  get disclosed() {\\n    return this._disclosed;\\n  }\\n  set disclosed(disclosed) {\\n    this._disclosed = disclosed;\\n  }\\n  get docID() {\\n    return this._docID;\\n  }\\n  set docID(_) {\\n    throw new Error(\\\"doc.docID is read-only\\\");\\n  }\\n  get documentFileName() {\\n    return this._documentFileName;\\n  }\\n  set documentFileName(_) {\\n    throw new Error(\\\"doc.documentFileName is read-only\\\");\\n  }\\n  get dynamicXFAForm() {\\n    return false;\\n  }\\n  set dynamicXFAForm(_) {\\n    throw new Error(\\\"doc.dynamicXFAForm is read-only\\\");\\n  }\\n  get external() {\\n    return DOC_EXTERNAL;\\n  }\\n  set external(_) {\\n    throw new Error(\\\"doc.external is read-only\\\");\\n  }\\n  get filesize() {\\n    return this._filesize;\\n  }\\n  set filesize(_) {\\n    throw new Error(\\\"doc.filesize is read-only\\\");\\n  }\\n  get hidden() {\\n    return false;\\n  }\\n  set hidden(_) {\\n    throw new Error(\\\"doc.hidden is read-only\\\");\\n  }\\n  get hostContainer() {\\n    return undefined;\\n  }\\n  set hostContainer(_) {\\n    throw new Error(\\\"doc.hostContainer is read-only\\\");\\n  }\\n  get icons() {\\n    return undefined;\\n  }\\n  set icons(_) {\\n    throw new Error(\\\"doc.icons is read-only\\\");\\n  }\\n  get info() {\\n    return this._info;\\n  }\\n  set info(_) {\\n    throw new Error(\\\"doc.info is read-only\\\");\\n  }\\n  get innerAppWindowRect() {\\n    return [0, 0, 0, 0];\\n  }\\n  set innerAppWindowRect(_) {\\n    throw new Error(\\\"doc.innerAppWindowRect is read-only\\\");\\n  }\\n  get innerDocWindowRect() {\\n    return [0, 0, 0, 0];\\n  }\\n  set innerDocWindowRect(_) {\\n    throw new Error(\\\"doc.innerDocWindowRect is read-only\\\");\\n  }\\n  get isModal() {\\n    return false;\\n  }\\n  set isModal(_) {\\n    throw new Error(\\\"doc.isModal is read-only\\\");\\n  }\\n  get keywords() {\\n    return this._keywords;\\n  }\\n  set keywords(_) {\\n    throw new Error(\\\"doc.keywords is read-only\\\");\\n  }\\n  get layout() {\\n    return this._layout;\\n  }\\n  set layout(value) {\\n    if (!this._userActivation) {\\n      return;\\n    }\\n    this._userActivation = false;\\n    if (typeof value !== \\\"string\\\") {\\n      return;\\n    }\\n    if (value !== \\\"SinglePage\\\" && value !== \\\"OneColumn\\\" && value !== \\\"TwoColumnLeft\\\" && value !== \\\"TwoPageLeft\\\" && value !== \\\"TwoColumnRight\\\" && value !== \\\"TwoPageRight\\\") {\\n      value = \\\"SinglePage\\\";\\n    }\\n    this._send({\\n      command: \\\"layout\\\",\\n      value\\n    });\\n    this._layout = value;\\n  }\\n  get media() {\\n    return this._media;\\n  }\\n  set media(media) {\\n    this._media = media;\\n  }\\n  get metadata() {\\n    return this._metadata;\\n  }\\n  set metadata(metadata) {\\n    this._metadata = metadata;\\n  }\\n  get modDate() {\\n    return this._modDate;\\n  }\\n  set modDate(_) {\\n    throw new Error(\\\"doc.modDate is read-only\\\");\\n  }\\n  get mouseX() {\\n    return 0;\\n  }\\n  set mouseX(_) {\\n    throw new Error(\\\"doc.mouseX is read-only\\\");\\n  }\\n  get mouseY() {\\n    return 0;\\n  }\\n  set mouseY(_) {\\n    throw new Error(\\\"doc.mouseY is read-only\\\");\\n  }\\n  get noautocomplete() {\\n    return this._noautocomplete;\\n  }\\n  set noautocomplete(noautocomplete) {\\n    this._noautocomplete = noautocomplete;\\n  }\\n  get nocache() {\\n    return this._nocache;\\n  }\\n  set nocache(nocache) {\\n    this._nocache = nocache;\\n  }\\n  get numFields() {\\n    return this._numFields;\\n  }\\n  set numFields(_) {\\n    throw new Error(\\\"doc.numFields is read-only\\\");\\n  }\\n  get numPages() {\\n    return this._numPages;\\n  }\\n  set numPages(_) {\\n    throw new Error(\\\"doc.numPages is read-only\\\");\\n  }\\n  get numTemplates() {\\n    return 0;\\n  }\\n  set numTemplates(_) {\\n    throw new Error(\\\"doc.numTemplates is read-only\\\");\\n  }\\n  get outerAppWindowRect() {\\n    return [0, 0, 0, 0];\\n  }\\n  set outerAppWindowRect(_) {\\n    throw new Error(\\\"doc.outerAppWindowRect is read-only\\\");\\n  }\\n  get outerDocWindowRect() {\\n    return [0, 0, 0, 0];\\n  }\\n  set outerDocWindowRect(_) {\\n    throw new Error(\\\"doc.outerDocWindowRect is read-only\\\");\\n  }\\n  get pageNum() {\\n    return this._pageNum;\\n  }\\n  set pageNum(value) {\\n    if (!this._userActivation) {\\n      return;\\n    }\\n    this._userActivation = false;\\n    if (typeof value !== \\\"number\\\" || value < 0 || value >= this._numPages) {\\n      return;\\n    }\\n    this._send({\\n      command: \\\"page-num\\\",\\n      value\\n    });\\n    this._pageNum = value;\\n  }\\n  get pageWindowRect() {\\n    return [0, 0, 0, 0];\\n  }\\n  set pageWindowRect(_) {\\n    throw new Error(\\\"doc.pageWindowRect is read-only\\\");\\n  }\\n  get path() {\\n    return \\\"\\\";\\n  }\\n  set path(_) {\\n    throw new Error(\\\"doc.path is read-only\\\");\\n  }\\n  get permStatusReady() {\\n    return true;\\n  }\\n  set permStatusReady(_) {\\n    throw new Error(\\\"doc.permStatusReady is read-only\\\");\\n  }\\n  get producer() {\\n    return this._producer;\\n  }\\n  set producer(_) {\\n    throw new Error(\\\"doc.producer is read-only\\\");\\n  }\\n  get requiresFullSave() {\\n    return false;\\n  }\\n  set requiresFullSave(_) {\\n    throw new Error(\\\"doc.requiresFullSave is read-only\\\");\\n  }\\n  get securityHandler() {\\n    return this._securityHandler;\\n  }\\n  set securityHandler(_) {\\n    throw new Error(\\\"doc.securityHandler is read-only\\\");\\n  }\\n  get selectedAnnots() {\\n    return [];\\n  }\\n  set selectedAnnots(_) {\\n    throw new Error(\\\"doc.selectedAnnots is read-only\\\");\\n  }\\n  get sounds() {\\n    return [];\\n  }\\n  set sounds(_) {\\n    throw new Error(\\\"doc.sounds is read-only\\\");\\n  }\\n  get spellDictionaryOrder() {\\n    return this._spellDictionaryOrder;\\n  }\\n  set spellDictionaryOrder(spellDictionaryOrder) {\\n    this._spellDictionaryOrder = spellDictionaryOrder;\\n  }\\n  get spellLanguageOrder() {\\n    return this._spellLanguageOrder;\\n  }\\n  set spellLanguageOrder(spellLanguageOrder) {\\n    this._spellLanguageOrder = spellLanguageOrder;\\n  }\\n  get subject() {\\n    return this._subject;\\n  }\\n  set subject(_) {\\n    throw new Error(\\\"doc.subject is read-only\\\");\\n  }\\n  get templates() {\\n    return [];\\n  }\\n  set templates(_) {\\n    throw new Error(\\\"doc.templates is read-only\\\");\\n  }\\n  get title() {\\n    return this._title;\\n  }\\n  set title(_) {\\n    throw new Error(\\\"doc.title is read-only\\\");\\n  }\\n  get URL() {\\n    return this._URL;\\n  }\\n  set URL(_) {\\n    throw new Error(\\\"doc.URL is read-only\\\");\\n  }\\n  get viewState() {\\n    return undefined;\\n  }\\n  set viewState(_) {\\n    throw new Error(\\\"doc.viewState is read-only\\\");\\n  }\\n  get xfa() {\\n    return this._xfa;\\n  }\\n  set xfa(_) {\\n    throw new Error(\\\"doc.xfa is read-only\\\");\\n  }\\n  get XFAForeground() {\\n    return false;\\n  }\\n  set XFAForeground(_) {\\n    throw new Error(\\\"doc.XFAForeground is read-only\\\");\\n  }\\n  get zoomType() {\\n    return this._zoomType;\\n  }\\n  set zoomType(type) {\\n    if (!this._userActivation) {\\n      return;\\n    }\\n    this._userActivation = false;\\n    if (typeof type !== \\\"string\\\") {\\n      return;\\n    }\\n    switch (type) {\\n      case ZoomType.none:\\n        this._send({\\n          command: \\\"zoom\\\",\\n          value: 1\\n        });\\n        break;\\n      case ZoomType.fitP:\\n        this._send({\\n          command: \\\"zoom\\\",\\n          value: \\\"page-fit\\\"\\n        });\\n        break;\\n      case ZoomType.fitW:\\n        this._send({\\n          command: \\\"zoom\\\",\\n          value: \\\"page-width\\\"\\n        });\\n        break;\\n      case ZoomType.fitH:\\n        this._send({\\n          command: \\\"zoom\\\",\\n          value: \\\"page-height\\\"\\n        });\\n        break;\\n      case ZoomType.fitV:\\n        this._send({\\n          command: \\\"zoom\\\",\\n          value: \\\"auto\\\"\\n        });\\n        break;\\n      case ZoomType.pref:\\n      case ZoomType.refW:\\n        break;\\n      default:\\n        return;\\n    }\\n    this._zoomType = type;\\n  }\\n  get zoom() {\\n    return this._zoom;\\n  }\\n  set zoom(value) {\\n    if (!this._userActivation) {\\n      return;\\n    }\\n    this._userActivation = false;\\n    if (typeof value !== \\\"number\\\" || value < 8.33 || value > 6400) {\\n      return;\\n    }\\n    this._send({\\n      command: \\\"zoom\\\",\\n      value: value / 100\\n    });\\n  }\\n  addAnnot() {}\\n  addField() {}\\n  addIcon() {}\\n  addLink() {}\\n  addRecipientListCryptFilter() {}\\n  addRequirement() {}\\n  addScript() {}\\n  addThumbnails() {}\\n  addWatermarkFromFile() {}\\n  addWatermarkFromText() {}\\n  addWeblinks() {}\\n  bringToFront() {}\\n  calculateNow() {\\n    this._eventDispatcher.calculateNow();\\n  }\\n  closeDoc() {}\\n  colorConvertPage() {}\\n  createDataObject() {}\\n  createTemplate() {}\\n  deletePages() {}\\n  deleteSound() {}\\n  embedDocAsDataObject() {}\\n  embedOutputIntent() {}\\n  encryptForRecipients() {}\\n  encryptUsingPolicy() {}\\n  exportAsFDF() {}\\n  exportAsFDFStr() {}\\n  exportAsText() {}\\n  exportAsXFDF() {}\\n  exportAsXFDFStr() {}\\n  exportDataObject() {}\\n  exportXFAData() {}\\n  extractPages() {}\\n  flattenPages() {}\\n  getAnnot() {}\\n  getAnnots() {}\\n  getAnnot3D() {}\\n  getAnnots3D() {}\\n  getColorConvertAction() {}\\n  getDataObject() {}\\n  getDataObjectContents() {}\\n  _getField(cName) {\\n    if (cName && typeof cName === \\\"object\\\") {\\n      cName = cName.cName;\\n    }\\n    if (typeof cName !== \\\"string\\\") {\\n      throw new TypeError(\\\"Invalid field name: must be a string\\\");\\n    }\\n    const searchedField = this._fields.get(cName);\\n    if (searchedField) {\\n      return searchedField;\\n    }\\n    const parts = cName.split(\\\"#\\\");\\n    let childIndex = NaN;\\n    if (parts.length === 2) {\\n      childIndex = Math.floor(parseFloat(parts[1]));\\n      cName = parts[0];\\n    }\\n    for (const [name, field] of this._fields.entries()) {\\n      if (name.endsWith(cName)) {\\n        if (!isNaN(childIndex)) {\\n          const children = this._getChildren(name);\\n          if (childIndex < 0 || childIndex >= children.length) {\\n            childIndex = 0;\\n          }\\n          if (childIndex < children.length) {\\n            this._fields.set(cName, children[childIndex]);\\n            return children[childIndex];\\n          }\\n        }\\n        this._fields.set(cName, field);\\n        return field;\\n      }\\n    }\\n    return null;\\n  }\\n  getField(cName) {\\n    const field = this._getField(cName);\\n    if (!field) {\\n      return null;\\n    }\\n    return field.wrapped;\\n  }\\n  _getChildren(fieldName) {\\n    const len = fieldName.length;\\n    const children = [];\\n    const pattern = /^\\\\.[^.]+$/;\\n    for (const [name, field] of this._fields.entries()) {\\n      if (name.startsWith(fieldName)) {\\n        const finalPart = name.slice(len);\\n        if (pattern.test(finalPart)) {\\n          children.push(field);\\n        }\\n      }\\n    }\\n    return children;\\n  }\\n  _getTerminalChildren(fieldName) {\\n    const children = [];\\n    const len = fieldName.length;\\n    for (const [name, field] of this._fields.entries()) {\\n      if (name.startsWith(fieldName)) {\\n        const finalPart = name.slice(len);\\n        if (field.obj._hasValue && (finalPart === \\\"\\\" || finalPart.startsWith(\\\".\\\"))) {\\n          children.push(field.wrapped);\\n        }\\n      }\\n    }\\n    return children;\\n  }\\n  getIcon() {}\\n  getLegalWarnings() {}\\n  getLinks() {}\\n  getNthFieldName(nIndex) {\\n    if (nIndex && typeof nIndex === \\\"object\\\") {\\n      nIndex = nIndex.nIndex;\\n    }\\n    if (typeof nIndex !== \\\"number\\\") {\\n      throw new TypeError(\\\"Invalid field index: must be a number\\\");\\n    }\\n    if (0 <= nIndex && nIndex < this.numFields) {\\n      return this._fieldNames[Math.trunc(nIndex)];\\n    }\\n    return null;\\n  }\\n  getNthTemplate() {\\n    return null;\\n  }\\n  getOCGs() {}\\n  getOCGOrder() {}\\n  getPageBox() {}\\n  getPageLabel() {}\\n  getPageNthWord() {}\\n  getPageNthWordQuads() {}\\n  getPageNumWords() {}\\n  getPageRotation() {}\\n  getPageTransition() {}\\n  getPrintParams() {\\n    return this._printParams ||= new PrintParams({\\n      lastPage: this._numPages - 1\\n    });\\n  }\\n  getSound() {}\\n  getTemplate() {}\\n  getURL() {}\\n  gotoNamedDest() {}\\n  importAnFDF() {}\\n  importAnXFDF() {}\\n  importDataObject() {}\\n  importIcon() {}\\n  importSound() {}\\n  importTextData() {}\\n  importXFAData() {}\\n  insertPages() {}\\n  mailDoc() {}\\n  mailForm() {}\\n  movePage() {}\\n  newPage() {}\\n  openDataObject() {}\\n  print(bUI = true, nStart = 0, nEnd = -1, bSilent = false, bShrinkToFit = false, bPrintAsImage = false, bReverse = false, bAnnotations = true, printParams = null) {\\n    if (this._disablePrinting || !this._userActivation) {\\n      return;\\n    }\\n    this._userActivation = false;\\n    if (bUI && typeof bUI === \\\"object\\\") {\\n      nStart = bUI.nStart;\\n      nEnd = bUI.nEnd;\\n      bSilent = bUI.bSilent;\\n      bShrinkToFit = bUI.bShrinkToFit;\\n      bPrintAsImage = bUI.bPrintAsImage;\\n      bReverse = bUI.bReverse;\\n      bAnnotations = bUI.bAnnotations;\\n      printParams = bUI.printParams;\\n      bUI = bUI.bUI;\\n    }\\n    if (printParams) {\\n      nStart = printParams.firstPage;\\n      nEnd = printParams.lastPage;\\n    }\\n    nStart = typeof nStart === \\\"number\\\" ? Math.max(0, Math.trunc(nStart)) : 0;\\n    nEnd = typeof nEnd === \\\"number\\\" ? Math.max(0, Math.trunc(nEnd)) : -1;\\n    this._send({\\n      command: \\\"print\\\",\\n      start: nStart,\\n      end: nEnd\\n    });\\n  }\\n  removeDataObject() {}\\n  removeField() {}\\n  removeIcon() {}\\n  removeLinks() {}\\n  removeRequirement() {}\\n  removeScript() {}\\n  removeTemplate() {}\\n  removeThumbnails() {}\\n  removeWeblinks() {}\\n  replacePages() {}\\n  resetForm(aFields = null) {\\n    if (aFields && typeof aFields === \\\"object\\\" && !Array.isArray(aFields)) {\\n      aFields = aFields.aFields;\\n    }\\n    if (aFields && !Array.isArray(aFields)) {\\n      aFields = [aFields];\\n    }\\n    let mustCalculate = false;\\n    let fieldsToReset;\\n    if (aFields) {\\n      fieldsToReset = [];\\n      for (const fieldName of aFields) {\\n        if (!fieldName) {\\n          continue;\\n        }\\n        if (typeof fieldName !== \\\"string\\\") {\\n          fieldsToReset = null;\\n          break;\\n        }\\n        const field = this._getField(fieldName);\\n        if (!field) {\\n          continue;\\n        }\\n        fieldsToReset.push(field);\\n        mustCalculate = true;\\n      }\\n    }\\n    if (!fieldsToReset) {\\n      fieldsToReset = this._fields.values();\\n      mustCalculate = this._fields.size !== 0;\\n    }\\n    for (const field of fieldsToReset) {\\n      field.obj.value = field.obj.defaultValue;\\n      this._send({\\n        id: field.obj._id,\\n        siblings: field.obj._siblings,\\n        value: field.obj.defaultValue,\\n        formattedValue: null,\\n        selRange: [0, 0]\\n      });\\n    }\\n    if (mustCalculate) {\\n      this.calculateNow();\\n    }\\n  }\\n  saveAs() {}\\n  scroll() {}\\n  selectPageNthWord() {}\\n  setAction() {}\\n  setDataObjectContents() {}\\n  setOCGOrder() {}\\n  setPageAction() {}\\n  setPageBoxes() {}\\n  setPageLabels() {}\\n  setPageRotations() {}\\n  setPageTabOrder() {}\\n  setPageTransitions() {}\\n  spawnPageFromTemplate() {}\\n  submitForm() {}\\n  syncAnnotScan() {}\\n}\\n\\n;// ./src/scripting_api/proxy.js\\nclass ProxyHandler {\\n  constructor() {\\n    this.nosend = new Set([\\\"delay\\\"]);\\n  }\\n  get(obj, prop) {\\n    if (prop in obj._expandos) {\\n      const val = obj._expandos[prop];\\n      if (typeof val === \\\"function\\\") {\\n        return val.bind(obj);\\n      }\\n      return val;\\n    }\\n    if (typeof prop === \\\"string\\\" && !prop.startsWith(\\\"_\\\") && prop in obj) {\\n      const val = obj[prop];\\n      if (typeof val === \\\"function\\\") {\\n        return val.bind(obj);\\n      }\\n      return val;\\n    }\\n    return undefined;\\n  }\\n  set(obj, prop, value) {\\n    if (obj._kidIds) {\\n      obj._kidIds.forEach(id => {\\n        obj._appObjects[id].wrapped[prop] = value;\\n      });\\n    }\\n    if (typeof prop === \\\"string\\\" && !prop.startsWith(\\\"_\\\") && prop in obj) {\\n      const old = obj[prop];\\n      obj[prop] = value;\\n      if (!this.nosend.has(prop) && obj._send && obj._id !== null && typeof old !== \\\"function\\\") {\\n        const data = {\\n          id: obj._id\\n        };\\n        data[prop] = prop === \\\"value\\\" ? obj._getValue() : obj[prop];\\n        if (!obj._siblings) {\\n          obj._send(data);\\n        } else {\\n          data.siblings = obj._siblings;\\n          obj._send(data);\\n        }\\n      }\\n    } else {\\n      obj._expandos[prop] = value;\\n    }\\n    return true;\\n  }\\n  has(obj, prop) {\\n    return prop in obj._expandos || typeof prop === \\\"string\\\" && !prop.startsWith(\\\"_\\\") && prop in obj;\\n  }\\n  getPrototypeOf(obj) {\\n    return null;\\n  }\\n  setPrototypeOf(obj, proto) {\\n    return false;\\n  }\\n  isExtensible(obj) {\\n    return true;\\n  }\\n  preventExtensions(obj) {\\n    return false;\\n  }\\n  getOwnPropertyDescriptor(obj, prop) {\\n    if (prop in obj._expandos) {\\n      return {\\n        configurable: true,\\n        enumerable: true,\\n        value: obj._expandos[prop]\\n      };\\n    }\\n    if (typeof prop === \\\"string\\\" && !prop.startsWith(\\\"_\\\") && prop in obj) {\\n      return {\\n        configurable: true,\\n        enumerable: true,\\n        value: obj[prop]\\n      };\\n    }\\n    return undefined;\\n  }\\n  defineProperty(obj, key, descriptor) {\\n    Object.defineProperty(obj._expandos, key, descriptor);\\n    return true;\\n  }\\n  deleteProperty(obj, prop) {\\n    if (prop in obj._expandos) {\\n      delete obj._expandos[prop];\\n    }\\n  }\\n  ownKeys(obj) {\\n    const fromExpandos = Reflect.ownKeys(obj._expandos);\\n    const fromObj = Reflect.ownKeys(obj).filter(k => !k.startsWith(\\\"_\\\"));\\n    return fromExpandos.concat(fromObj);\\n  }\\n}\\n\\n;// ./src/scripting_api/util.js\\n\\nclass Util extends PDFObject {\\n  constructor(data) {\\n    super(data);\\n    this._scandCache = new Map();\\n    this._months = [\\\"January\\\", \\\"February\\\", \\\"March\\\", \\\"April\\\", \\\"May\\\", \\\"June\\\", \\\"July\\\", \\\"August\\\", \\\"September\\\", \\\"October\\\", \\\"November\\\", \\\"December\\\"];\\n    this._days = [\\\"Sunday\\\", \\\"Monday\\\", \\\"Tuesday\\\", \\\"Wednesday\\\", \\\"Thursday\\\", \\\"Friday\\\", \\\"Saturday\\\"];\\n    this.MILLISECONDS_IN_DAY = 86400000;\\n    this.MILLISECONDS_IN_WEEK = 604800000;\\n    this._externalCall = data.externalCall;\\n  }\\n  printf(...args) {\\n    if (args.length === 0) {\\n      throw new Error(\\\"Invalid number of params in printf\\\");\\n    }\\n    if (typeof args[0] !== \\\"string\\\") {\\n      throw new TypeError(\\\"First argument of printf must be a string\\\");\\n    }\\n    const pattern = /%(,[0-4])?([+ 0#]+)?(\\\\d+)?(\\\\.\\\\d+)?(.)/g;\\n    const PLUS = 1;\\n    const SPACE = 2;\\n    const ZERO = 4;\\n    const HASH = 8;\\n    let i = 0;\\n    return args[0].replaceAll(pattern, function (match, nDecSep, cFlags, nWidth, nPrecision, cConvChar) {\\n      if (cConvChar !== \\\"d\\\" && cConvChar !== \\\"f\\\" && cConvChar !== \\\"s\\\" && cConvChar !== \\\"x\\\") {\\n        const buf = [\\\"%\\\"];\\n        for (const str of [nDecSep, cFlags, nWidth, nPrecision, cConvChar]) {\\n          if (str) {\\n            buf.push(str);\\n          }\\n        }\\n        return buf.join(\\\"\\\");\\n      }\\n      i++;\\n      if (i === args.length) {\\n        throw new Error(\\\"Not enough arguments in printf\\\");\\n      }\\n      const arg = args[i];\\n      if (cConvChar === \\\"s\\\") {\\n        return arg.toString();\\n      }\\n      let flags = 0;\\n      if (cFlags) {\\n        for (const flag of cFlags) {\\n          switch (flag) {\\n            case \\\"+\\\":\\n              flags |= PLUS;\\n              break;\\n            case \\\" \\\":\\n              flags |= SPACE;\\n              break;\\n            case \\\"0\\\":\\n              flags |= ZERO;\\n              break;\\n            case \\\"#\\\":\\n              flags |= HASH;\\n              break;\\n          }\\n        }\\n      }\\n      cFlags = flags;\\n      if (nWidth) {\\n        nWidth = parseInt(nWidth);\\n      }\\n      let intPart = Math.trunc(arg);\\n      if (cConvChar === \\\"x\\\") {\\n        let hex = Math.abs(intPart).toString(16).toUpperCase();\\n        if (nWidth !== undefined) {\\n          hex = hex.padStart(nWidth, cFlags & ZERO ? \\\"0\\\" : \\\" \\\");\\n        }\\n        if (cFlags & HASH) {\\n          hex = `0x${hex}`;\\n        }\\n        return hex;\\n      }\\n      if (nPrecision) {\\n        nPrecision = parseInt(nPrecision.substring(1));\\n      }\\n      nDecSep = nDecSep ? nDecSep.substring(1) : \\\"0\\\";\\n      const separators = {\\n        0: [\\\",\\\", \\\".\\\"],\\n        1: [\\\"\\\", \\\".\\\"],\\n        2: [\\\".\\\", \\\",\\\"],\\n        3: [\\\"\\\", \\\",\\\"],\\n        4: [\\\"'\\\", \\\".\\\"]\\n      };\\n      const [thousandSep, decimalSep] = separators[nDecSep];\\n      let decPart = \\\"\\\";\\n      if (cConvChar === \\\"f\\\") {\\n        decPart = nPrecision !== undefined ? Math.abs(arg - intPart).toFixed(nPrecision) : Math.abs(arg - intPart).toString();\\n        if (decPart.length > 2) {\\n          decPart = `${decimalSep}${decPart.substring(2)}`;\\n        } else {\\n          if (decPart === \\\"1\\\") {\\n            intPart += Math.sign(arg);\\n          }\\n          decPart = cFlags & HASH ? \\\".\\\" : \\\"\\\";\\n        }\\n      }\\n      let sign = \\\"\\\";\\n      if (intPart < 0) {\\n        sign = \\\"-\\\";\\n        intPart = -intPart;\\n      } else if (cFlags & PLUS) {\\n        sign = \\\"+\\\";\\n      } else if (cFlags & SPACE) {\\n        sign = \\\" \\\";\\n      }\\n      if (thousandSep && intPart >= 1000) {\\n        const buf = [];\\n        while (true) {\\n          buf.push((intPart % 1000).toString().padStart(3, \\\"0\\\"));\\n          intPart = Math.trunc(intPart / 1000);\\n          if (intPart < 1000) {\\n            buf.push(intPart.toString());\\n            break;\\n          }\\n        }\\n        intPart = buf.reverse().join(thousandSep);\\n      } else {\\n        intPart = intPart.toString();\\n      }\\n      let n = `${intPart}${decPart}`;\\n      if (nWidth !== undefined) {\\n        n = n.padStart(nWidth - sign.length, cFlags & ZERO ? \\\"0\\\" : \\\" \\\");\\n      }\\n      return `${sign}${n}`;\\n    });\\n  }\\n  iconStreamFromIcon() {}\\n  printd(cFormat, oDate) {\\n    switch (cFormat) {\\n      case 0:\\n        return this.printd(\\\"D:yyyymmddHHMMss\\\", oDate);\\n      case 1:\\n        return this.printd(\\\"yyyy.mm.dd HH:MM:ss\\\", oDate);\\n      case 2:\\n        return this.printd(\\\"m/d/yy h:MM:ss tt\\\", oDate);\\n    }\\n    const handlers = {\\n      mmmm: data => this._months[data.month],\\n      mmm: data => this._months[data.month].substring(0, 3),\\n      mm: data => (data.month + 1).toString().padStart(2, \\\"0\\\"),\\n      m: data => (data.month + 1).toString(),\\n      dddd: data => this._days[data.dayOfWeek],\\n      ddd: data => this._days[data.dayOfWeek].substring(0, 3),\\n      dd: data => data.day.toString().padStart(2, \\\"0\\\"),\\n      d: data => data.day.toString(),\\n      yyyy: data => data.year.toString(),\\n      yy: data => (data.year % 100).toString().padStart(2, \\\"0\\\"),\\n      HH: data => data.hours.toString().padStart(2, \\\"0\\\"),\\n      H: data => data.hours.toString(),\\n      hh: data => (1 + (data.hours + 11) % 12).toString().padStart(2, \\\"0\\\"),\\n      h: data => (1 + (data.hours + 11) % 12).toString(),\\n      MM: data => data.minutes.toString().padStart(2, \\\"0\\\"),\\n      M: data => data.minutes.toString(),\\n      ss: data => data.seconds.toString().padStart(2, \\\"0\\\"),\\n      s: data => data.seconds.toString(),\\n      tt: data => data.hours < 12 ? \\\"am\\\" : \\\"pm\\\",\\n      t: data => data.hours < 12 ? \\\"a\\\" : \\\"p\\\"\\n    };\\n    const data = {\\n      year: oDate.getFullYear(),\\n      month: oDate.getMonth(),\\n      day: oDate.getDate(),\\n      dayOfWeek: oDate.getDay(),\\n      hours: oDate.getHours(),\\n      minutes: oDate.getMinutes(),\\n      seconds: oDate.getSeconds()\\n    };\\n    const patterns = /(mmmm|mmm|mm|m|dddd|ddd|dd|d|yyyy|yy|HH|H|hh|h|MM|M|ss|s|tt|t|\\\\\\\\.)/g;\\n    return cFormat.replaceAll(patterns, function (match, pattern) {\\n      if (pattern in handlers) {\\n        return handlers[pattern](data);\\n      }\\n      return pattern.charCodeAt(1);\\n    });\\n  }\\n  printx(cFormat, cSource) {\\n    cSource = (cSource ?? \\\"\\\").toString();\\n    const handlers = [x => x, x => x.toUpperCase(), x => x.toLowerCase()];\\n    const buf = [];\\n    let i = 0;\\n    const ii = cSource.length;\\n    let currCase = handlers[0];\\n    let escaped = false;\\n    for (const command of cFormat) {\\n      if (escaped) {\\n        buf.push(command);\\n        escaped = false;\\n        continue;\\n      }\\n      if (i >= ii) {\\n        break;\\n      }\\n      switch (command) {\\n        case \\\"?\\\":\\n          buf.push(currCase(cSource.charAt(i++)));\\n          break;\\n        case \\\"X\\\":\\n          while (i < ii) {\\n            const char = cSource.charAt(i++);\\n            if (\\\"a\\\" <= char && char <= \\\"z\\\" || \\\"A\\\" <= char && char <= \\\"Z\\\" || \\\"0\\\" <= char && char <= \\\"9\\\") {\\n              buf.push(currCase(char));\\n              break;\\n            }\\n          }\\n          break;\\n        case \\\"A\\\":\\n          while (i < ii) {\\n            const char = cSource.charAt(i++);\\n            if (\\\"a\\\" <= char && char <= \\\"z\\\" || \\\"A\\\" <= char && char <= \\\"Z\\\") {\\n              buf.push(currCase(char));\\n              break;\\n            }\\n          }\\n          break;\\n        case \\\"9\\\":\\n          while (i < ii) {\\n            const char = cSource.charAt(i++);\\n            if (\\\"0\\\" <= char && char <= \\\"9\\\") {\\n              buf.push(char);\\n              break;\\n            }\\n          }\\n          break;\\n        case \\\"*\\\":\\n          while (i < ii) {\\n            buf.push(currCase(cSource.charAt(i++)));\\n          }\\n          break;\\n        case \\\"\\\\\\\\\\\":\\n          escaped = true;\\n          break;\\n        case \\\">\\\":\\n          currCase = handlers[1];\\n          break;\\n        case \\\"<\\\":\\n          currCase = handlers[2];\\n          break;\\n        case \\\"=\\\":\\n          currCase = handlers[0];\\n          break;\\n        default:\\n          buf.push(command);\\n      }\\n    }\\n    return buf.join(\\\"\\\");\\n  }\\n  scand(cFormat, cDate) {\\n    if (typeof cDate !== \\\"string\\\") {\\n      return new Date(cDate);\\n    }\\n    if (cDate === \\\"\\\") {\\n      return new Date();\\n    }\\n    switch (cFormat) {\\n      case 0:\\n        return this.scand(\\\"D:yyyymmddHHMMss\\\", cDate);\\n      case 1:\\n        return this.scand(\\\"yyyy.mm.dd HH:MM:ss\\\", cDate);\\n      case 2:\\n        return this.scand(\\\"m/d/yy h:MM:ss tt\\\", cDate);\\n    }\\n    if (!this._scandCache.has(cFormat)) {\\n      const months = this._months;\\n      const days = this._days;\\n      const handlers = {\\n        mmmm: {\\n          pattern: `(${months.join(\\\"|\\\")})`,\\n          action: (value, data) => {\\n            data.month = months.indexOf(value);\\n          }\\n        },\\n        mmm: {\\n          pattern: `(${months.map(month => month.substring(0, 3)).join(\\\"|\\\")})`,\\n          action: (value, data) => {\\n            data.month = months.findIndex(month => month.substring(0, 3) === value);\\n          }\\n        },\\n        mm: {\\n          pattern: `(\\\\\\\\d{2})`,\\n          action: (value, data) => {\\n            data.month = parseInt(value) - 1;\\n          }\\n        },\\n        m: {\\n          pattern: `(\\\\\\\\d{1,2})`,\\n          action: (value, data) => {\\n            data.month = parseInt(value) - 1;\\n          }\\n        },\\n        dddd: {\\n          pattern: `(${days.join(\\\"|\\\")})`,\\n          action: (value, data) => {\\n            data.day = days.indexOf(value);\\n          }\\n        },\\n        ddd: {\\n          pattern: `(${days.map(day => day.substring(0, 3)).join(\\\"|\\\")})`,\\n          action: (value, data) => {\\n            data.day = days.findIndex(day => day.substring(0, 3) === value);\\n          }\\n        },\\n        dd: {\\n          pattern: \\\"(\\\\\\\\d{2})\\\",\\n          action: (value, data) => {\\n            data.day = parseInt(value);\\n          }\\n        },\\n        d: {\\n          pattern: \\\"(\\\\\\\\d{1,2})\\\",\\n          action: (value, data) => {\\n            data.day = parseInt(value);\\n          }\\n        },\\n        yyyy: {\\n          pattern: \\\"(\\\\\\\\d{4})\\\",\\n          action: (value, data) => {\\n            data.year = parseInt(value);\\n          }\\n        },\\n        yy: {\\n          pattern: \\\"(\\\\\\\\d{2})\\\",\\n          action: (value, data) => {\\n            data.year = 2000 + parseInt(value);\\n          }\\n        },\\n        HH: {\\n          pattern: \\\"(\\\\\\\\d{2})\\\",\\n          action: (value, data) => {\\n            data.hours = parseInt(value);\\n          }\\n        },\\n        H: {\\n          pattern: \\\"(\\\\\\\\d{1,2})\\\",\\n          action: (value, data) => {\\n            data.hours = parseInt(value);\\n          }\\n        },\\n        hh: {\\n          pattern: \\\"(\\\\\\\\d{2})\\\",\\n          action: (value, data) => {\\n            data.hours = parseInt(value);\\n          }\\n        },\\n        h: {\\n          pattern: \\\"(\\\\\\\\d{1,2})\\\",\\n          action: (value, data) => {\\n            data.hours = parseInt(value);\\n          }\\n        },\\n        MM: {\\n          pattern: \\\"(\\\\\\\\d{2})\\\",\\n          action: (value, data) => {\\n            data.minutes = parseInt(value);\\n          }\\n        },\\n        M: {\\n          pattern: \\\"(\\\\\\\\d{1,2})\\\",\\n          action: (value, data) => {\\n            data.minutes = parseInt(value);\\n          }\\n        },\\n        ss: {\\n          pattern: \\\"(\\\\\\\\d{2})\\\",\\n          action: (value, data) => {\\n            data.seconds = parseInt(value);\\n          }\\n        },\\n        s: {\\n          pattern: \\\"(\\\\\\\\d{1,2})\\\",\\n          action: (value, data) => {\\n            data.seconds = parseInt(value);\\n          }\\n        },\\n        tt: {\\n          pattern: \\\"([aApP][mM])\\\",\\n          action: (value, data) => {\\n            const char = value.charAt(0);\\n            data.am = char === \\\"a\\\" || char === \\\"A\\\";\\n          }\\n        },\\n        t: {\\n          pattern: \\\"([aApP])\\\",\\n          action: (value, data) => {\\n            data.am = value === \\\"a\\\" || value === \\\"A\\\";\\n          }\\n        }\\n      };\\n      const escapedFormat = cFormat.replaceAll(/[.*+\\\\-?^${}()|[\\\\]\\\\\\\\]/g, \\\"\\\\\\\\$&\\\");\\n      const patterns = /(mmmm|mmm|mm|m|dddd|ddd|dd|d|yyyy|yy|HH|H|hh|h|MM|M|ss|s|tt|t)/g;\\n      const actions = [];\\n      const re = escapedFormat.replaceAll(patterns, function (match, patternElement) {\\n        const {\\n          pattern,\\n          action\\n        } = handlers[patternElement];\\n        actions.push(action);\\n        return pattern;\\n      });\\n      this._scandCache.set(cFormat, [re, actions]);\\n    }\\n    const [re, actions] = this._scandCache.get(cFormat);\\n    const matches = new RegExp(`^${re}$`, \\\"g\\\").exec(cDate);\\n    if (!matches || matches.length !== actions.length + 1) {\\n      return null;\\n    }\\n    const data = {\\n      year: 2000,\\n      month: 0,\\n      day: 1,\\n      hours: 0,\\n      minutes: 0,\\n      seconds: 0,\\n      am: null\\n    };\\n    actions.forEach((action, i) => action(matches[i + 1], data));\\n    if (data.am !== null) {\\n      data.hours = data.hours % 12 + (data.am ? 0 : 12);\\n    }\\n    return new Date(data.year, data.month, data.day, data.hours, data.minutes, data.seconds);\\n  }\\n  spansToXML() {}\\n  stringFromStream() {}\\n  xmlToSpans() {}\\n}\\n\\n;// ./src/scripting_api/initialization.js\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\nfunction initSandbox(params) {\\n  delete globalThis.pdfjsScripting;\\n  const externalCall = globalThis.callExternalFunction;\\n  delete globalThis.callExternalFunction;\\n  const globalEval = code => globalThis.eval(code);\\n  const send = data => externalCall(\\\"send\\\", [data]);\\n  const proxyHandler = new ProxyHandler();\\n  const {\\n    data\\n  } = params;\\n  const doc = new Doc({\\n    send,\\n    globalEval,\\n    ...data.docInfo\\n  });\\n  const _document = {\\n    obj: doc,\\n    wrapped: new Proxy(doc, proxyHandler)\\n  };\\n  const app = new App({\\n    send,\\n    globalEval,\\n    externalCall,\\n    _document,\\n    calculationOrder: data.calculationOrder,\\n    proxyHandler,\\n    ...data.appInfo\\n  });\\n  const util = new Util({\\n    externalCall\\n  });\\n  const appObjects = app._objects;\\n  if (data.objects) {\\n    const annotations = [];\\n    for (const [name, objs] of Object.entries(data.objects)) {\\n      annotations.length = 0;\\n      let container = null;\\n      for (const obj of objs) {\\n        if (obj.type !== \\\"\\\") {\\n          annotations.push(obj);\\n        } else {\\n          container = obj;\\n        }\\n      }\\n      let obj = container;\\n      if (annotations.length > 0) {\\n        obj = annotations[0];\\n        obj.send = send;\\n      }\\n      obj.globalEval = globalEval;\\n      obj.doc = _document;\\n      obj.fieldPath = name;\\n      obj.appObjects = appObjects;\\n      let field;\\n      switch (obj.type) {\\n        case \\\"radiobutton\\\":\\n          {\\n            const otherButtons = annotations.slice(1);\\n            field = new RadioButtonField(otherButtons, obj);\\n            break;\\n          }\\n        case \\\"checkbox\\\":\\n          {\\n            const otherButtons = annotations.slice(1);\\n            field = new CheckboxField(otherButtons, obj);\\n            break;\\n          }\\n        case \\\"text\\\":\\n          if (annotations.length <= 1) {\\n            field = new Field(obj);\\n            break;\\n          }\\n          obj.siblings = annotations.map(x => x.id).slice(1);\\n          field = new Field(obj);\\n          break;\\n        default:\\n          field = new Field(obj);\\n      }\\n      const wrapped = new Proxy(field, proxyHandler);\\n      const _object = {\\n        obj: field,\\n        wrapped\\n      };\\n      doc._addField(name, _object);\\n      for (const object of objs) {\\n        appObjects[object.id] = _object;\\n      }\\n      if (container) {\\n        appObjects[container.id] = _object;\\n      }\\n    }\\n  }\\n  const color = new Color();\\n  globalThis.event = null;\\n  globalThis.global = Object.create(null);\\n  globalThis.app = new Proxy(app, proxyHandler);\\n  globalThis.color = new Proxy(color, proxyHandler);\\n  globalThis.console = new Proxy(new Console({\\n    send\\n  }), proxyHandler);\\n  globalThis.util = new Proxy(util, proxyHandler);\\n  globalThis.border = Border;\\n  globalThis.cursor = Cursor;\\n  globalThis.display = Display;\\n  globalThis.font = Font;\\n  globalThis.highlight = Highlight;\\n  globalThis.position = Position;\\n  globalThis.scaleHow = ScaleHow;\\n  globalThis.scaleWhen = ScaleWhen;\\n  globalThis.style = Style;\\n  globalThis.trans = Trans;\\n  globalThis.zoomtype = ZoomType;\\n  globalThis.ADBE = {\\n    Reader_Value_Asked: true,\\n    Viewer_Value_Asked: true\\n  };\\n  const aform = new AForm(doc, app, util, color);\\n  for (const name of Object.getOwnPropertyNames(AForm.prototype)) {\\n    if (name !== \\\"constructor\\\" && !name.startsWith(\\\"_\\\")) {\\n      globalThis[name] = aform[name].bind(aform);\\n    }\\n  }\\n  for (const [name, value] of Object.entries(GlobalConstants)) {\\n    Object.defineProperty(globalThis, name, {\\n      value,\\n      writable: false\\n    });\\n  }\\n  Object.defineProperties(globalThis, {\\n    ColorConvert: {\\n      value: color.convert.bind(color),\\n      writable: true\\n    },\\n    ColorEqual: {\\n      value: color.equal.bind(color),\\n      writable: true\\n    }\\n  });\\n  const properties = Object.create(null);\\n  for (const name of Object.getOwnPropertyNames(Doc.prototype)) {\\n    if (name === \\\"constructor\\\" || name.startsWith(\\\"_\\\")) {\\n      continue;\\n    }\\n    const descriptor = Object.getOwnPropertyDescriptor(Doc.prototype, name);\\n    if (descriptor.get) {\\n      properties[name] = {\\n        get: descriptor.get.bind(doc),\\n        set: descriptor.set.bind(doc)\\n      };\\n    } else {\\n      properties[name] = {\\n        value: Doc.prototype[name].bind(doc)\\n      };\\n    }\\n  }\\n  Object.defineProperties(globalThis, properties);\\n  const functions = {\\n    dispatchEvent: app._dispatchEvent.bind(app),\\n    timeoutCb: app._evalCallback.bind(app)\\n  };\\n  return (name, args) => {\\n    try {\\n      functions[name](args);\\n    } catch (error) {\\n      send(serializeError(error));\\n    }\\n  };\\n}\\n\\n;// ./src/pdf.scripting.js\\n\\nconst pdfjsVersion = \\\"4.1.0\\\";\\nconst pdfjsBuild = \\\"849f8548b1\\\";\\nglobalThis.pdfjsScripting = {\\n  initSandbox: initSandbox\\n};\\n\"];\n    code.push(\"delete dump;\");\n    let success = false;\n    let buf = 0;\n    try {\n      const sandboxData = JSON.stringify(data);\n      code.push(`pdfjsScripting.initSandbox({ data: ${sandboxData} })`);\n      buf = this._module.stringToNewUTF8(code.join(\"\\n\"));\n      success = !!this._module.ccall(\"init\", \"number\", [\"number\", \"number\"], [buf, this._alertOnError]);\n    } catch (error) {\n      console.error(error);\n    } finally {\n      if (buf) {\n        this._module.ccall(\"free\", \"number\", [\"number\"], [buf]);\n      }\n    }\n    if (success) {\n      this.support.commFun = this._module.cwrap(\"commFun\", null, [\"string\", \"string\"]);\n    } else {\n      this.nukeSandbox();\n      throw new Error(\"Cannot start sandbox\");\n    }\n  }\n  dispatchEvent(event) {\n    this.support?.callSandboxFunction(\"dispatchEvent\", event);\n  }\n  dumpMemoryUse() {\n    this._module?.ccall(\"dumpMemoryUse\", null, []);\n  }\n  nukeSandbox() {\n    if (this._module !== null) {\n      this.support.destroy();\n      this.support = null;\n      this._module.ccall(\"nukeSandbox\", null, []);\n      this._module = null;\n    }\n  }\n  evalForTesting(code, key) {\n    throw new Error(\"Not implemented: evalForTesting\");\n  }\n}\nfunction QuickJSSandbox() {\n  return quickjs_eval().then(module => new Sandbox(window, module));\n}\n\nexport { QuickJSSandbox };\n\n//# sourceMappingURL=pdf.sandbox.mjs.map"
  },
  {
    "path": "src/vendor/pdfjs/pdf.worker.mjs",
    "content": "/**\n * @licstart The following is the entire license notice for the\n * JavaScript code in this page\n *\n * Copyright 2023 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @licend The above is the entire license notice for the\n * JavaScript code in this page\n */\n\nimport { createRequire as __WEBPACK_EXTERNAL_createRequire } from \"node:module\";\n\n;// ./src/shared/util.js\nconst isNodeJS = typeof process === \"object\" && process + \"\" === \"[object process]\" && !process.versions.nw && !(process.versions.electron && process.type && process.type !== \"browser\");\nconst IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];\nconst FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];\nconst MAX_IMAGE_SIZE_TO_CACHE = 10e6;\nconst LINE_FACTOR = 1.35;\nconst LINE_DESCENT_FACTOR = 0.35;\nconst BASELINE_FACTOR = LINE_DESCENT_FACTOR / LINE_FACTOR;\nconst RenderingIntentFlag = {\n  ANY: 0x01,\n  DISPLAY: 0x02,\n  PRINT: 0x04,\n  SAVE: 0x08,\n  ANNOTATIONS_FORMS: 0x10,\n  ANNOTATIONS_STORAGE: 0x20,\n  ANNOTATIONS_DISABLE: 0x40,\n  OPLIST: 0x100\n};\nconst AnnotationMode = {\n  DISABLE: 0,\n  ENABLE: 1,\n  ENABLE_FORMS: 2,\n  ENABLE_STORAGE: 3\n};\nconst AnnotationEditorPrefix = \"pdfjs_internal_editor_\";\nconst AnnotationEditorType = {\n  DISABLE: -1,\n  NONE: 0,\n  FREETEXT: 3,\n  HIGHLIGHT: 9,\n  STAMP: 13,\n  INK: 15\n};\nconst AnnotationEditorParamsType = {\n  RESIZE: 1,\n  CREATE: 2,\n  FREETEXT_SIZE: 11,\n  FREETEXT_COLOR: 12,\n  FREETEXT_OPACITY: 13,\n  INK_COLOR: 21,\n  INK_THICKNESS: 22,\n  INK_OPACITY: 23,\n  HIGHLIGHT_COLOR: 31,\n  HIGHLIGHT_DEFAULT_COLOR: 32,\n  HIGHLIGHT_THICKNESS: 33,\n  HIGHLIGHT_FREE: 34,\n  HIGHLIGHT_SHOW_ALL: 35\n};\nconst PermissionFlag = {\n  PRINT: 0x04,\n  MODIFY_CONTENTS: 0x08,\n  COPY: 0x10,\n  MODIFY_ANNOTATIONS: 0x20,\n  FILL_INTERACTIVE_FORMS: 0x100,\n  COPY_FOR_ACCESSIBILITY: 0x200,\n  ASSEMBLE: 0x400,\n  PRINT_HIGH_QUALITY: 0x800\n};\nconst TextRenderingMode = {\n  FILL: 0,\n  STROKE: 1,\n  FILL_STROKE: 2,\n  INVISIBLE: 3,\n  FILL_ADD_TO_PATH: 4,\n  STROKE_ADD_TO_PATH: 5,\n  FILL_STROKE_ADD_TO_PATH: 6,\n  ADD_TO_PATH: 7,\n  FILL_STROKE_MASK: 3,\n  ADD_TO_PATH_FLAG: 4\n};\nconst ImageKind = {\n  GRAYSCALE_1BPP: 1,\n  RGB_24BPP: 2,\n  RGBA_32BPP: 3\n};\nconst AnnotationType = {\n  TEXT: 1,\n  LINK: 2,\n  FREETEXT: 3,\n  LINE: 4,\n  SQUARE: 5,\n  CIRCLE: 6,\n  POLYGON: 7,\n  POLYLINE: 8,\n  HIGHLIGHT: 9,\n  UNDERLINE: 10,\n  SQUIGGLY: 11,\n  STRIKEOUT: 12,\n  STAMP: 13,\n  CARET: 14,\n  INK: 15,\n  POPUP: 16,\n  FILEATTACHMENT: 17,\n  SOUND: 18,\n  MOVIE: 19,\n  WIDGET: 20,\n  SCREEN: 21,\n  PRINTERMARK: 22,\n  TRAPNET: 23,\n  WATERMARK: 24,\n  THREED: 25,\n  REDACT: 26\n};\nconst AnnotationReplyType = {\n  GROUP: \"Group\",\n  REPLY: \"R\"\n};\nconst AnnotationFlag = {\n  INVISIBLE: 0x01,\n  HIDDEN: 0x02,\n  PRINT: 0x04,\n  NOZOOM: 0x08,\n  NOROTATE: 0x10,\n  NOVIEW: 0x20,\n  READONLY: 0x40,\n  LOCKED: 0x80,\n  TOGGLENOVIEW: 0x100,\n  LOCKEDCONTENTS: 0x200\n};\nconst AnnotationFieldFlag = {\n  READONLY: 0x0000001,\n  REQUIRED: 0x0000002,\n  NOEXPORT: 0x0000004,\n  MULTILINE: 0x0001000,\n  PASSWORD: 0x0002000,\n  NOTOGGLETOOFF: 0x0004000,\n  RADIO: 0x0008000,\n  PUSHBUTTON: 0x0010000,\n  COMBO: 0x0020000,\n  EDIT: 0x0040000,\n  SORT: 0x0080000,\n  FILESELECT: 0x0100000,\n  MULTISELECT: 0x0200000,\n  DONOTSPELLCHECK: 0x0400000,\n  DONOTSCROLL: 0x0800000,\n  COMB: 0x1000000,\n  RICHTEXT: 0x2000000,\n  RADIOSINUNISON: 0x2000000,\n  COMMITONSELCHANGE: 0x4000000\n};\nconst AnnotationBorderStyleType = {\n  SOLID: 1,\n  DASHED: 2,\n  BEVELED: 3,\n  INSET: 4,\n  UNDERLINE: 5\n};\nconst AnnotationActionEventType = {\n  E: \"Mouse Enter\",\n  X: \"Mouse Exit\",\n  D: \"Mouse Down\",\n  U: \"Mouse Up\",\n  Fo: \"Focus\",\n  Bl: \"Blur\",\n  PO: \"PageOpen\",\n  PC: \"PageClose\",\n  PV: \"PageVisible\",\n  PI: \"PageInvisible\",\n  K: \"Keystroke\",\n  F: \"Format\",\n  V: \"Validate\",\n  C: \"Calculate\"\n};\nconst DocumentActionEventType = {\n  WC: \"WillClose\",\n  WS: \"WillSave\",\n  DS: \"DidSave\",\n  WP: \"WillPrint\",\n  DP: \"DidPrint\"\n};\nconst PageActionEventType = {\n  O: \"PageOpen\",\n  C: \"PageClose\"\n};\nconst VerbosityLevel = {\n  ERRORS: 0,\n  WARNINGS: 1,\n  INFOS: 5\n};\nconst CMapCompressionType = {\n  NONE: 0,\n  BINARY: 1\n};\nconst OPS = {\n  dependency: 1,\n  setLineWidth: 2,\n  setLineCap: 3,\n  setLineJoin: 4,\n  setMiterLimit: 5,\n  setDash: 6,\n  setRenderingIntent: 7,\n  setFlatness: 8,\n  setGState: 9,\n  save: 10,\n  restore: 11,\n  transform: 12,\n  moveTo: 13,\n  lineTo: 14,\n  curveTo: 15,\n  curveTo2: 16,\n  curveTo3: 17,\n  closePath: 18,\n  rectangle: 19,\n  stroke: 20,\n  closeStroke: 21,\n  fill: 22,\n  eoFill: 23,\n  fillStroke: 24,\n  eoFillStroke: 25,\n  closeFillStroke: 26,\n  closeEOFillStroke: 27,\n  endPath: 28,\n  clip: 29,\n  eoClip: 30,\n  beginText: 31,\n  endText: 32,\n  setCharSpacing: 33,\n  setWordSpacing: 34,\n  setHScale: 35,\n  setLeading: 36,\n  setFont: 37,\n  setTextRenderingMode: 38,\n  setTextRise: 39,\n  moveText: 40,\n  setLeadingMoveText: 41,\n  setTextMatrix: 42,\n  nextLine: 43,\n  showText: 44,\n  showSpacedText: 45,\n  nextLineShowText: 46,\n  nextLineSetSpacingShowText: 47,\n  setCharWidth: 48,\n  setCharWidthAndBounds: 49,\n  setStrokeColorSpace: 50,\n  setFillColorSpace: 51,\n  setStrokeColor: 52,\n  setStrokeColorN: 53,\n  setFillColor: 54,\n  setFillColorN: 55,\n  setStrokeGray: 56,\n  setFillGray: 57,\n  setStrokeRGBColor: 58,\n  setFillRGBColor: 59,\n  setStrokeCMYKColor: 60,\n  setFillCMYKColor: 61,\n  shadingFill: 62,\n  beginInlineImage: 63,\n  beginImageData: 64,\n  endInlineImage: 65,\n  paintXObject: 66,\n  markPoint: 67,\n  markPointProps: 68,\n  beginMarkedContent: 69,\n  beginMarkedContentProps: 70,\n  endMarkedContent: 71,\n  beginCompat: 72,\n  endCompat: 73,\n  paintFormXObjectBegin: 74,\n  paintFormXObjectEnd: 75,\n  beginGroup: 76,\n  endGroup: 77,\n  beginAnnotation: 80,\n  endAnnotation: 81,\n  paintImageMaskXObject: 83,\n  paintImageMaskXObjectGroup: 84,\n  paintImageXObject: 85,\n  paintInlineImageXObject: 86,\n  paintInlineImageXObjectGroup: 87,\n  paintImageXObjectRepeat: 88,\n  paintImageMaskXObjectRepeat: 89,\n  paintSolidColorImageMask: 90,\n  constructPath: 91\n};\nconst PasswordResponses = {\n  NEED_PASSWORD: 1,\n  INCORRECT_PASSWORD: 2\n};\nlet verbosity = VerbosityLevel.WARNINGS;\nfunction setVerbosityLevel(level) {\n  if (Number.isInteger(level)) {\n    verbosity = level;\n  }\n}\nfunction getVerbosityLevel() {\n  return verbosity;\n}\nfunction info(msg) {\n  if (verbosity >= VerbosityLevel.INFOS) {\n    console.error(`Info: ${msg}`);\n  }\n}\nfunction warn(msg) {\n  if (verbosity >= VerbosityLevel.WARNINGS) {\n    console.error(`Warning: ${msg}`);\n  }\n}\nfunction unreachable(msg) {\n  throw new Error(msg);\n}\nfunction assert(cond, msg) {\n  if (!cond) {\n    unreachable(msg);\n  }\n}\nfunction _isValidProtocol(url) {\n  switch (url?.protocol) {\n    case \"http:\":\n    case \"https:\":\n    case \"ftp:\":\n    case \"mailto:\":\n    case \"tel:\":\n      return true;\n    default:\n      return false;\n  }\n}\nfunction createValidAbsoluteUrl(url, baseUrl = null, options = null) {\n  if (!url) {\n    return null;\n  }\n  try {\n    if (options && typeof url === \"string\") {\n      if (options.addDefaultProtocol && url.startsWith(\"www.\")) {\n        const dots = url.match(/\\./g);\n        if (dots?.length >= 2) {\n          url = `http://${url}`;\n        }\n      }\n      if (options.tryConvertEncoding) {\n        try {\n          url = stringToUTF8String(url);\n        } catch {}\n      }\n    }\n    const absoluteUrl = baseUrl ? new URL(url, baseUrl) : new URL(url);\n    if (_isValidProtocol(absoluteUrl)) {\n      return absoluteUrl;\n    }\n  } catch {}\n  return null;\n}\nfunction shadow(obj, prop, value, nonSerializable = false) {\n  Object.defineProperty(obj, prop, {\n    value,\n    enumerable: !nonSerializable,\n    configurable: true,\n    writable: false\n  });\n  return value;\n}\nconst BaseException = function BaseExceptionClosure() {\n  function BaseException(message, name) {\n    if (this.constructor === BaseException) {\n      unreachable(\"Cannot initialize BaseException.\");\n    }\n    this.message = message;\n    this.name = name;\n  }\n  BaseException.prototype = new Error();\n  BaseException.constructor = BaseException;\n  return BaseException;\n}();\nclass PasswordException extends BaseException {\n  constructor(msg, code) {\n    super(msg, \"PasswordException\");\n    this.code = code;\n  }\n}\nclass UnknownErrorException extends BaseException {\n  constructor(msg, details) {\n    super(msg, \"UnknownErrorException\");\n    this.details = details;\n  }\n}\nclass InvalidPDFException extends BaseException {\n  constructor(msg) {\n    super(msg, \"InvalidPDFException\");\n  }\n}\nclass MissingPDFException extends BaseException {\n  constructor(msg) {\n    super(msg, \"MissingPDFException\");\n  }\n}\nclass UnexpectedResponseException extends BaseException {\n  constructor(msg, status) {\n    super(msg, \"UnexpectedResponseException\");\n    this.status = status;\n  }\n}\nclass FormatError extends BaseException {\n  constructor(msg) {\n    super(msg, \"FormatError\");\n  }\n}\nclass AbortException extends BaseException {\n  constructor(msg) {\n    super(msg, \"AbortException\");\n  }\n}\nfunction bytesToString(bytes) {\n  if (typeof bytes !== \"object\" || bytes?.length === undefined) {\n    unreachable(\"Invalid argument for bytesToString\");\n  }\n  const length = bytes.length;\n  const MAX_ARGUMENT_COUNT = 8192;\n  if (length < MAX_ARGUMENT_COUNT) {\n    return String.fromCharCode.apply(null, bytes);\n  }\n  const strBuf = [];\n  for (let i = 0; i < length; i += MAX_ARGUMENT_COUNT) {\n    const chunkEnd = Math.min(i + MAX_ARGUMENT_COUNT, length);\n    const chunk = bytes.subarray(i, chunkEnd);\n    strBuf.push(String.fromCharCode.apply(null, chunk));\n  }\n  return strBuf.join(\"\");\n}\nfunction stringToBytes(str) {\n  if (typeof str !== \"string\") {\n    unreachable(\"Invalid argument for stringToBytes\");\n  }\n  const length = str.length;\n  const bytes = new Uint8Array(length);\n  for (let i = 0; i < length; ++i) {\n    bytes[i] = str.charCodeAt(i) & 0xff;\n  }\n  return bytes;\n}\nfunction string32(value) {\n  return String.fromCharCode(value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff);\n}\nfunction objectSize(obj) {\n  return Object.keys(obj).length;\n}\nfunction objectFromMap(map) {\n  const obj = Object.create(null);\n  for (const [key, value] of map) {\n    obj[key] = value;\n  }\n  return obj;\n}\nfunction isLittleEndian() {\n  const buffer8 = new Uint8Array(4);\n  buffer8[0] = 1;\n  const view32 = new Uint32Array(buffer8.buffer, 0, 1);\n  return view32[0] === 1;\n}\nfunction isEvalSupported() {\n  try {\n    new Function(\"\");\n    return true;\n  } catch {\n    return false;\n  }\n}\nclass FeatureTest {\n  static get isLittleEndian() {\n    return shadow(this, \"isLittleEndian\", isLittleEndian());\n  }\n  static get isEvalSupported() {\n    return shadow(this, \"isEvalSupported\", isEvalSupported());\n  }\n  static get isOffscreenCanvasSupported() {\n    return shadow(this, \"isOffscreenCanvasSupported\", typeof OffscreenCanvas !== \"undefined\");\n  }\n  static get platform() {\n    if (typeof navigator !== \"undefined\" && typeof navigator?.platform === \"string\") {\n      return shadow(this, \"platform\", {\n        isMac: navigator.platform.includes(\"Mac\")\n      });\n    }\n    return shadow(this, \"platform\", {\n      isMac: false\n    });\n  }\n  static get isCSSRoundSupported() {\n    return shadow(this, \"isCSSRoundSupported\", globalThis.CSS?.supports?.(\"width: round(1.5px, 1px)\"));\n  }\n}\nconst hexNumbers = Array.from(Array(256).keys(), n => n.toString(16).padStart(2, \"0\"));\nclass Util {\n  static makeHexColor(r, g, b) {\n    return `#${hexNumbers[r]}${hexNumbers[g]}${hexNumbers[b]}`;\n  }\n  static scaleMinMax(transform, minMax) {\n    let temp;\n    if (transform[0]) {\n      if (transform[0] < 0) {\n        temp = minMax[0];\n        minMax[0] = minMax[2];\n        minMax[2] = temp;\n      }\n      minMax[0] *= transform[0];\n      minMax[2] *= transform[0];\n      if (transform[3] < 0) {\n        temp = minMax[1];\n        minMax[1] = minMax[3];\n        minMax[3] = temp;\n      }\n      minMax[1] *= transform[3];\n      minMax[3] *= transform[3];\n    } else {\n      temp = minMax[0];\n      minMax[0] = minMax[1];\n      minMax[1] = temp;\n      temp = minMax[2];\n      minMax[2] = minMax[3];\n      minMax[3] = temp;\n      if (transform[1] < 0) {\n        temp = minMax[1];\n        minMax[1] = minMax[3];\n        minMax[3] = temp;\n      }\n      minMax[1] *= transform[1];\n      minMax[3] *= transform[1];\n      if (transform[2] < 0) {\n        temp = minMax[0];\n        minMax[0] = minMax[2];\n        minMax[2] = temp;\n      }\n      minMax[0] *= transform[2];\n      minMax[2] *= transform[2];\n    }\n    minMax[0] += transform[4];\n    minMax[1] += transform[5];\n    minMax[2] += transform[4];\n    minMax[3] += transform[5];\n  }\n  static transform(m1, m2) {\n    return [m1[0] * m2[0] + m1[2] * m2[1], m1[1] * m2[0] + m1[3] * m2[1], m1[0] * m2[2] + m1[2] * m2[3], m1[1] * m2[2] + m1[3] * m2[3], m1[0] * m2[4] + m1[2] * m2[5] + m1[4], m1[1] * m2[4] + m1[3] * m2[5] + m1[5]];\n  }\n  static applyTransform(p, m) {\n    const xt = p[0] * m[0] + p[1] * m[2] + m[4];\n    const yt = p[0] * m[1] + p[1] * m[3] + m[5];\n    return [xt, yt];\n  }\n  static applyInverseTransform(p, m) {\n    const d = m[0] * m[3] - m[1] * m[2];\n    const xt = (p[0] * m[3] - p[1] * m[2] + m[2] * m[5] - m[4] * m[3]) / d;\n    const yt = (-p[0] * m[1] + p[1] * m[0] + m[4] * m[1] - m[5] * m[0]) / d;\n    return [xt, yt];\n  }\n  static getAxialAlignedBoundingBox(r, m) {\n    const p1 = this.applyTransform(r, m);\n    const p2 = this.applyTransform(r.slice(2, 4), m);\n    const p3 = this.applyTransform([r[0], r[3]], m);\n    const p4 = this.applyTransform([r[2], r[1]], m);\n    return [Math.min(p1[0], p2[0], p3[0], p4[0]), Math.min(p1[1], p2[1], p3[1], p4[1]), Math.max(p1[0], p2[0], p3[0], p4[0]), Math.max(p1[1], p2[1], p3[1], p4[1])];\n  }\n  static inverseTransform(m) {\n    const d = m[0] * m[3] - m[1] * m[2];\n    return [m[3] / d, -m[1] / d, -m[2] / d, m[0] / d, (m[2] * m[5] - m[4] * m[3]) / d, (m[4] * m[1] - m[5] * m[0]) / d];\n  }\n  static getRotation(m) {\n    return Math.atan2(m[1], m[0]) * (180 / Math.PI);\n  }\n  static singularValueDecompose2dScale(m) {\n    const transpose = [m[0], m[2], m[1], m[3]];\n    const a = m[0] * transpose[0] + m[1] * transpose[2];\n    const b = m[0] * transpose[1] + m[1] * transpose[3];\n    const c = m[2] * transpose[0] + m[3] * transpose[2];\n    const d = m[2] * transpose[1] + m[3] * transpose[3];\n    const first = (a + d) / 2;\n    const second = Math.sqrt((a + d) ** 2 - 4 * (a * d - c * b)) / 2;\n    const sx = first + second || 1;\n    const sy = first - second || 1;\n    return [Math.sqrt(sx), Math.sqrt(sy)];\n  }\n  static normalizeRect(rect) {\n    const r = rect.slice(0);\n    if (rect[0] > rect[2]) {\n      r[0] = rect[2];\n      r[2] = rect[0];\n    }\n    if (rect[1] > rect[3]) {\n      r[1] = rect[3];\n      r[3] = rect[1];\n    }\n    return r;\n  }\n  static intersect(rect1, rect2) {\n    const xLow = Math.max(Math.min(rect1[0], rect1[2]), Math.min(rect2[0], rect2[2]));\n    const xHigh = Math.min(Math.max(rect1[0], rect1[2]), Math.max(rect2[0], rect2[2]));\n    if (xLow > xHigh) {\n      return null;\n    }\n    const yLow = Math.max(Math.min(rect1[1], rect1[3]), Math.min(rect2[1], rect2[3]));\n    const yHigh = Math.min(Math.max(rect1[1], rect1[3]), Math.max(rect2[1], rect2[3]));\n    if (yLow > yHigh) {\n      return null;\n    }\n    return [xLow, yLow, xHigh, yHigh];\n  }\n  static #getExtremumOnCurve(x0, x1, x2, x3, y0, y1, y2, y3, t, minMax) {\n    if (t <= 0 || t >= 1) {\n      return;\n    }\n    const mt = 1 - t;\n    const tt = t * t;\n    const ttt = tt * t;\n    const x = mt * (mt * (mt * x0 + 3 * t * x1) + 3 * tt * x2) + ttt * x3;\n    const y = mt * (mt * (mt * y0 + 3 * t * y1) + 3 * tt * y2) + ttt * y3;\n    minMax[0] = Math.min(minMax[0], x);\n    minMax[1] = Math.min(minMax[1], y);\n    minMax[2] = Math.max(minMax[2], x);\n    minMax[3] = Math.max(minMax[3], y);\n  }\n  static #getExtremum(x0, x1, x2, x3, y0, y1, y2, y3, a, b, c, minMax) {\n    if (Math.abs(a) < 1e-12) {\n      if (Math.abs(b) >= 1e-12) {\n        this.#getExtremumOnCurve(x0, x1, x2, x3, y0, y1, y2, y3, -c / b, minMax);\n      }\n      return;\n    }\n    const delta = b ** 2 - 4 * c * a;\n    if (delta < 0) {\n      return;\n    }\n    const sqrtDelta = Math.sqrt(delta);\n    const a2 = 2 * a;\n    this.#getExtremumOnCurve(x0, x1, x2, x3, y0, y1, y2, y3, (-b + sqrtDelta) / a2, minMax);\n    this.#getExtremumOnCurve(x0, x1, x2, x3, y0, y1, y2, y3, (-b - sqrtDelta) / a2, minMax);\n  }\n  static bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3, minMax) {\n    if (minMax) {\n      minMax[0] = Math.min(minMax[0], x0, x3);\n      minMax[1] = Math.min(minMax[1], y0, y3);\n      minMax[2] = Math.max(minMax[2], x0, x3);\n      minMax[3] = Math.max(minMax[3], y0, y3);\n    } else {\n      minMax = [Math.min(x0, x3), Math.min(y0, y3), Math.max(x0, x3), Math.max(y0, y3)];\n    }\n    this.#getExtremum(x0, x1, x2, x3, y0, y1, y2, y3, 3 * (-x0 + 3 * (x1 - x2) + x3), 6 * (x0 - 2 * x1 + x2), 3 * (x1 - x0), minMax);\n    this.#getExtremum(x0, x1, x2, x3, y0, y1, y2, y3, 3 * (-y0 + 3 * (y1 - y2) + y3), 6 * (y0 - 2 * y1 + y2), 3 * (y1 - y0), minMax);\n    return minMax;\n  }\n}\nconst PDFStringTranslateTable = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2d8, 0x2c7, 0x2c6, 0x2d9, 0x2dd, 0x2db, 0x2da, 0x2dc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x192, 0x2044, 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018, 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x141, 0x152, 0x160, 0x178, 0x17d, 0x131, 0x142, 0x153, 0x161, 0x17e, 0, 0x20ac];\nfunction stringToPDFString(str) {\n  if (str[0] >= \"\\xEF\") {\n    let encoding;\n    if (str[0] === \"\\xFE\" && str[1] === \"\\xFF\") {\n      encoding = \"utf-16be\";\n      if (str.length % 2 === 1) {\n        str = str.slice(0, -1);\n      }\n    } else if (str[0] === \"\\xFF\" && str[1] === \"\\xFE\") {\n      encoding = \"utf-16le\";\n      if (str.length % 2 === 1) {\n        str = str.slice(0, -1);\n      }\n    } else if (str[0] === \"\\xEF\" && str[1] === \"\\xBB\" && str[2] === \"\\xBF\") {\n      encoding = \"utf-8\";\n    }\n    if (encoding) {\n      try {\n        const decoder = new TextDecoder(encoding, {\n          fatal: true\n        });\n        const buffer = stringToBytes(str);\n        const decoded = decoder.decode(buffer);\n        if (!decoded.includes(\"\\x1b\")) {\n          return decoded;\n        }\n        return decoded.replaceAll(/\\x1b[^\\x1b]*(?:\\x1b|$)/g, \"\");\n      } catch (ex) {\n        warn(`stringToPDFString: \"${ex}\".`);\n      }\n    }\n  }\n  const strBuf = [];\n  for (let i = 0, ii = str.length; i < ii; i++) {\n    const charCode = str.charCodeAt(i);\n    if (charCode === 0x1b) {\n      while (++i < ii && str.charCodeAt(i) !== 0x1b) {}\n      continue;\n    }\n    const code = PDFStringTranslateTable[charCode];\n    strBuf.push(code ? String.fromCharCode(code) : str.charAt(i));\n  }\n  return strBuf.join(\"\");\n}\nfunction stringToUTF8String(str) {\n  return decodeURIComponent(escape(str));\n}\nfunction utf8StringToString(str) {\n  return unescape(encodeURIComponent(str));\n}\nfunction isArrayEqual(arr1, arr2) {\n  if (arr1.length !== arr2.length) {\n    return false;\n  }\n  for (let i = 0, ii = arr1.length; i < ii; i++) {\n    if (arr1[i] !== arr2[i]) {\n      return false;\n    }\n  }\n  return true;\n}\nfunction getModificationDate(date = new Date()) {\n  const buffer = [date.getUTCFullYear().toString(), (date.getUTCMonth() + 1).toString().padStart(2, \"0\"), date.getUTCDate().toString().padStart(2, \"0\"), date.getUTCHours().toString().padStart(2, \"0\"), date.getUTCMinutes().toString().padStart(2, \"0\"), date.getUTCSeconds().toString().padStart(2, \"0\")];\n  return buffer.join(\"\");\n}\nclass PromiseCapability {\n  #settled = false;\n  constructor() {\n    this.promise = new Promise((resolve, reject) => {\n      this.resolve = data => {\n        this.#settled = true;\n        resolve(data);\n      };\n      this.reject = reason => {\n        this.#settled = true;\n        reject(reason);\n      };\n    });\n  }\n  get settled() {\n    return this.#settled;\n  }\n}\nlet NormalizeRegex = null;\nlet NormalizationMap = null;\nfunction normalizeUnicode(str) {\n  if (!NormalizeRegex) {\n    NormalizeRegex = /([\\u00a0\\u00b5\\u037e\\u0eb3\\u2000-\\u200a\\u202f\\u2126\\ufb00-\\ufb04\\ufb06\\ufb20-\\ufb36\\ufb38-\\ufb3c\\ufb3e\\ufb40-\\ufb41\\ufb43-\\ufb44\\ufb46-\\ufba1\\ufba4-\\ufba9\\ufbae-\\ufbb1\\ufbd3-\\ufbdc\\ufbde-\\ufbe7\\ufbea-\\ufbf8\\ufbfc-\\ufbfd\\ufc00-\\ufc5d\\ufc64-\\ufcf1\\ufcf5-\\ufd3d\\ufd88\\ufdf4\\ufdfa-\\ufdfb\\ufe71\\ufe77\\ufe79\\ufe7b\\ufe7d]+)|(\\ufb05+)/gu;\n    NormalizationMap = new Map([[\"ﬅ\", \"ſt\"]]);\n  }\n  return str.replaceAll(NormalizeRegex, (_, p1, p2) => p1 ? p1.normalize(\"NFKC\") : NormalizationMap.get(p2));\n}\nfunction getUuid() {\n  if (typeof crypto !== \"undefined\" && typeof crypto?.randomUUID === \"function\") {\n    return crypto.randomUUID();\n  }\n  const buf = new Uint8Array(32);\n  if (typeof crypto !== \"undefined\" && typeof crypto?.getRandomValues === \"function\") {\n    crypto.getRandomValues(buf);\n  } else {\n    for (let i = 0; i < 32; i++) {\n      buf[i] = Math.floor(Math.random() * 255);\n    }\n  }\n  return bytesToString(buf);\n}\nconst AnnotationPrefix = \"pdfjs_internal_id_\";\n\n;// ./src/core/primitives.js\n\nconst CIRCULAR_REF = Symbol(\"CIRCULAR_REF\");\nconst EOF = Symbol(\"EOF\");\nlet CmdCache = Object.create(null);\nlet NameCache = Object.create(null);\nlet RefCache = Object.create(null);\nfunction clearPrimitiveCaches() {\n  CmdCache = Object.create(null);\n  NameCache = Object.create(null);\n  RefCache = Object.create(null);\n}\nclass Name {\n  constructor(name) {\n    this.name = name;\n  }\n  static get(name) {\n    return NameCache[name] ||= new Name(name);\n  }\n}\nclass Cmd {\n  constructor(cmd) {\n    this.cmd = cmd;\n  }\n  static get(cmd) {\n    return CmdCache[cmd] ||= new Cmd(cmd);\n  }\n}\nconst nonSerializable = function nonSerializableClosure() {\n  return nonSerializable;\n};\nclass Dict {\n  constructor(xref = null) {\n    this._map = Object.create(null);\n    this.xref = xref;\n    this.objId = null;\n    this.suppressEncryption = false;\n    this.__nonSerializable__ = nonSerializable;\n  }\n  assignXref(newXref) {\n    this.xref = newXref;\n  }\n  get size() {\n    return Object.keys(this._map).length;\n  }\n  get(key1, key2, key3) {\n    let value = this._map[key1];\n    if (value === undefined && key2 !== undefined) {\n      value = this._map[key2];\n      if (value === undefined && key3 !== undefined) {\n        value = this._map[key3];\n      }\n    }\n    if (value instanceof Ref && this.xref) {\n      return this.xref.fetch(value, this.suppressEncryption);\n    }\n    return value;\n  }\n  async getAsync(key1, key2, key3) {\n    let value = this._map[key1];\n    if (value === undefined && key2 !== undefined) {\n      value = this._map[key2];\n      if (value === undefined && key3 !== undefined) {\n        value = this._map[key3];\n      }\n    }\n    if (value instanceof Ref && this.xref) {\n      return this.xref.fetchAsync(value, this.suppressEncryption);\n    }\n    return value;\n  }\n  getArray(key1, key2, key3) {\n    let value = this._map[key1];\n    if (value === undefined && key2 !== undefined) {\n      value = this._map[key2];\n      if (value === undefined && key3 !== undefined) {\n        value = this._map[key3];\n      }\n    }\n    if (value instanceof Ref && this.xref) {\n      value = this.xref.fetch(value, this.suppressEncryption);\n    }\n    if (Array.isArray(value)) {\n      value = value.slice();\n      for (let i = 0, ii = value.length; i < ii; i++) {\n        if (value[i] instanceof Ref && this.xref) {\n          value[i] = this.xref.fetch(value[i], this.suppressEncryption);\n        }\n      }\n    }\n    return value;\n  }\n  getRaw(key) {\n    return this._map[key];\n  }\n  getKeys() {\n    return Object.keys(this._map);\n  }\n  getRawValues() {\n    return Object.values(this._map);\n  }\n  set(key, value) {\n    this._map[key] = value;\n  }\n  has(key) {\n    return this._map[key] !== undefined;\n  }\n  forEach(callback) {\n    for (const key in this._map) {\n      callback(key, this.get(key));\n    }\n  }\n  static get empty() {\n    const emptyDict = new Dict(null);\n    emptyDict.set = (key, value) => {\n      unreachable(\"Should not call `set` on the empty dictionary.\");\n    };\n    return shadow(this, \"empty\", emptyDict);\n  }\n  static merge({\n    xref,\n    dictArray,\n    mergeSubDicts = false\n  }) {\n    const mergedDict = new Dict(xref),\n      properties = new Map();\n    for (const dict of dictArray) {\n      if (!(dict instanceof Dict)) {\n        continue;\n      }\n      for (const [key, value] of Object.entries(dict._map)) {\n        let property = properties.get(key);\n        if (property === undefined) {\n          property = [];\n          properties.set(key, property);\n        } else if (!mergeSubDicts || !(value instanceof Dict)) {\n          continue;\n        }\n        property.push(value);\n      }\n    }\n    for (const [name, values] of properties) {\n      if (values.length === 1 || !(values[0] instanceof Dict)) {\n        mergedDict._map[name] = values[0];\n        continue;\n      }\n      const subDict = new Dict(xref);\n      for (const dict of values) {\n        for (const [key, value] of Object.entries(dict._map)) {\n          if (subDict._map[key] === undefined) {\n            subDict._map[key] = value;\n          }\n        }\n      }\n      if (subDict.size > 0) {\n        mergedDict._map[name] = subDict;\n      }\n    }\n    properties.clear();\n    return mergedDict.size > 0 ? mergedDict : Dict.empty;\n  }\n  clone() {\n    const dict = new Dict(this.xref);\n    for (const key of this.getKeys()) {\n      dict.set(key, this.getRaw(key));\n    }\n    return dict;\n  }\n}\nclass Ref {\n  constructor(num, gen) {\n    this.num = num;\n    this.gen = gen;\n  }\n  toString() {\n    if (this.gen === 0) {\n      return `${this.num}R`;\n    }\n    return `${this.num}R${this.gen}`;\n  }\n  static fromString(str) {\n    const ref = RefCache[str];\n    if (ref) {\n      return ref;\n    }\n    const m = /^(\\d+)R(\\d*)$/.exec(str);\n    if (!m || m[1] === \"0\") {\n      return null;\n    }\n    return RefCache[str] = new Ref(parseInt(m[1]), !m[2] ? 0 : parseInt(m[2]));\n  }\n  static get(num, gen) {\n    const key = gen === 0 ? `${num}R` : `${num}R${gen}`;\n    return RefCache[key] ||= new Ref(num, gen);\n  }\n}\nclass RefSet {\n  constructor(parent = null) {\n    this._set = new Set(parent?._set);\n  }\n  has(ref) {\n    return this._set.has(ref.toString());\n  }\n  put(ref) {\n    this._set.add(ref.toString());\n  }\n  remove(ref) {\n    this._set.delete(ref.toString());\n  }\n  [Symbol.iterator]() {\n    return this._set.values();\n  }\n  clear() {\n    this._set.clear();\n  }\n}\nclass RefSetCache {\n  constructor() {\n    this._map = new Map();\n  }\n  get size() {\n    return this._map.size;\n  }\n  get(ref) {\n    return this._map.get(ref.toString());\n  }\n  has(ref) {\n    return this._map.has(ref.toString());\n  }\n  put(ref, obj) {\n    this._map.set(ref.toString(), obj);\n  }\n  putAlias(ref, aliasRef) {\n    this._map.set(ref.toString(), this.get(aliasRef));\n  }\n  [Symbol.iterator]() {\n    return this._map.values();\n  }\n  clear() {\n    this._map.clear();\n  }\n}\nfunction isName(v, name) {\n  return v instanceof Name && (name === undefined || v.name === name);\n}\nfunction isCmd(v, cmd) {\n  return v instanceof Cmd && (cmd === undefined || v.cmd === cmd);\n}\nfunction isDict(v, type) {\n  return v instanceof Dict && (type === undefined || isName(v.get(\"Type\"), type));\n}\nfunction isRefsEqual(v1, v2) {\n  return v1.num === v2.num && v1.gen === v2.gen;\n}\n\n;// ./src/core/base_stream.js\n\nclass BaseStream {\n  constructor() {\n    if (this.constructor === BaseStream) {\n      unreachable(\"Cannot initialize BaseStream.\");\n    }\n  }\n  get length() {\n    unreachable(\"Abstract getter `length` accessed\");\n  }\n  get isEmpty() {\n    unreachable(\"Abstract getter `isEmpty` accessed\");\n  }\n  get isDataLoaded() {\n    return shadow(this, \"isDataLoaded\", true);\n  }\n  getByte() {\n    unreachable(\"Abstract method `getByte` called\");\n  }\n  getBytes(length) {\n    unreachable(\"Abstract method `getBytes` called\");\n  }\n  peekByte() {\n    const peekedByte = this.getByte();\n    if (peekedByte !== -1) {\n      this.pos--;\n    }\n    return peekedByte;\n  }\n  peekBytes(length) {\n    const bytes = this.getBytes(length);\n    this.pos -= bytes.length;\n    return bytes;\n  }\n  getUint16() {\n    const b0 = this.getByte();\n    const b1 = this.getByte();\n    if (b0 === -1 || b1 === -1) {\n      return -1;\n    }\n    return (b0 << 8) + b1;\n  }\n  getInt32() {\n    const b0 = this.getByte();\n    const b1 = this.getByte();\n    const b2 = this.getByte();\n    const b3 = this.getByte();\n    return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3;\n  }\n  getByteRange(begin, end) {\n    unreachable(\"Abstract method `getByteRange` called\");\n  }\n  getString(length) {\n    return bytesToString(this.getBytes(length));\n  }\n  skip(n) {\n    this.pos += n || 1;\n  }\n  reset() {\n    unreachable(\"Abstract method `reset` called\");\n  }\n  moveStart() {\n    unreachable(\"Abstract method `moveStart` called\");\n  }\n  makeSubStream(start, length, dict = null) {\n    unreachable(\"Abstract method `makeSubStream` called\");\n  }\n  getBaseStreams() {\n    return null;\n  }\n}\n\n;// ./src/core/core_utils.js\n\n\n\nconst PDF_VERSION_REGEXP = /^[1-9]\\.\\d$/;\nfunction getLookupTableFactory(initializer) {\n  let lookup;\n  return function () {\n    if (initializer) {\n      lookup = Object.create(null);\n      initializer(lookup);\n      initializer = null;\n    }\n    return lookup;\n  };\n}\nclass MissingDataException extends BaseException {\n  constructor(begin, end) {\n    super(`Missing data [${begin}, ${end})`, \"MissingDataException\");\n    this.begin = begin;\n    this.end = end;\n  }\n}\nclass ParserEOFException extends BaseException {\n  constructor(msg) {\n    super(msg, \"ParserEOFException\");\n  }\n}\nclass XRefEntryException extends BaseException {\n  constructor(msg) {\n    super(msg, \"XRefEntryException\");\n  }\n}\nclass XRefParseException extends BaseException {\n  constructor(msg) {\n    super(msg, \"XRefParseException\");\n  }\n}\nfunction arrayBuffersToBytes(arr) {\n  const length = arr.length;\n  if (length === 0) {\n    return new Uint8Array(0);\n  }\n  if (length === 1) {\n    return new Uint8Array(arr[0]);\n  }\n  let dataLength = 0;\n  for (let i = 0; i < length; i++) {\n    dataLength += arr[i].byteLength;\n  }\n  const data = new Uint8Array(dataLength);\n  let pos = 0;\n  for (let i = 0; i < length; i++) {\n    const item = new Uint8Array(arr[i]);\n    data.set(item, pos);\n    pos += item.byteLength;\n  }\n  return data;\n}\nfunction getInheritableProperty({\n  dict,\n  key,\n  getArray = false,\n  stopWhenFound = true\n}) {\n  let values;\n  const visited = new RefSet();\n  while (dict instanceof Dict && !(dict.objId && visited.has(dict.objId))) {\n    if (dict.objId) {\n      visited.put(dict.objId);\n    }\n    const value = getArray ? dict.getArray(key) : dict.get(key);\n    if (value !== undefined) {\n      if (stopWhenFound) {\n        return value;\n      }\n      (values ||= []).push(value);\n    }\n    dict = dict.get(\"Parent\");\n  }\n  return values;\n}\nconst ROMAN_NUMBER_MAP = [\"\", \"C\", \"CC\", \"CCC\", \"CD\", \"D\", \"DC\", \"DCC\", \"DCCC\", \"CM\", \"\", \"X\", \"XX\", \"XXX\", \"XL\", \"L\", \"LX\", \"LXX\", \"LXXX\", \"XC\", \"\", \"I\", \"II\", \"III\", \"IV\", \"V\", \"VI\", \"VII\", \"VIII\", \"IX\"];\nfunction toRomanNumerals(number, lowerCase = false) {\n  assert(Number.isInteger(number) && number > 0, \"The number should be a positive integer.\");\n  const romanBuf = [];\n  let pos;\n  while (number >= 1000) {\n    number -= 1000;\n    romanBuf.push(\"M\");\n  }\n  pos = number / 100 | 0;\n  number %= 100;\n  romanBuf.push(ROMAN_NUMBER_MAP[pos]);\n  pos = number / 10 | 0;\n  number %= 10;\n  romanBuf.push(ROMAN_NUMBER_MAP[10 + pos]);\n  romanBuf.push(ROMAN_NUMBER_MAP[20 + number]);\n  const romanStr = romanBuf.join(\"\");\n  return lowerCase ? romanStr.toLowerCase() : romanStr;\n}\nfunction log2(x) {\n  if (x <= 0) {\n    return 0;\n  }\n  return Math.ceil(Math.log2(x));\n}\nfunction readInt8(data, offset) {\n  return data[offset] << 24 >> 24;\n}\nfunction readUint16(data, offset) {\n  return data[offset] << 8 | data[offset + 1];\n}\nfunction readUint32(data, offset) {\n  return (data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]) >>> 0;\n}\nfunction isWhiteSpace(ch) {\n  return ch === 0x20 || ch === 0x09 || ch === 0x0d || ch === 0x0a;\n}\nfunction parseXFAPath(path) {\n  const positionPattern = /(.+)\\[(\\d+)\\]$/;\n  return path.split(\".\").map(component => {\n    const m = component.match(positionPattern);\n    if (m) {\n      return {\n        name: m[1],\n        pos: parseInt(m[2], 10)\n      };\n    }\n    return {\n      name: component,\n      pos: 0\n    };\n  });\n}\nfunction escapePDFName(str) {\n  const buffer = [];\n  let start = 0;\n  for (let i = 0, ii = str.length; i < ii; i++) {\n    const char = str.charCodeAt(i);\n    if (char < 0x21 || char > 0x7e || char === 0x23 || char === 0x28 || char === 0x29 || char === 0x3c || char === 0x3e || char === 0x5b || char === 0x5d || char === 0x7b || char === 0x7d || char === 0x2f || char === 0x25) {\n      if (start < i) {\n        buffer.push(str.substring(start, i));\n      }\n      buffer.push(`#${char.toString(16)}`);\n      start = i + 1;\n    }\n  }\n  if (buffer.length === 0) {\n    return str;\n  }\n  if (start < str.length) {\n    buffer.push(str.substring(start, str.length));\n  }\n  return buffer.join(\"\");\n}\nfunction escapeString(str) {\n  return str.replaceAll(/([()\\\\\\n\\r])/g, match => {\n    if (match === \"\\n\") {\n      return \"\\\\n\";\n    } else if (match === \"\\r\") {\n      return \"\\\\r\";\n    }\n    return `\\\\${match}`;\n  });\n}\nfunction _collectJS(entry, xref, list, parents) {\n  if (!entry) {\n    return;\n  }\n  let parent = null;\n  if (entry instanceof Ref) {\n    if (parents.has(entry)) {\n      return;\n    }\n    parent = entry;\n    parents.put(parent);\n    entry = xref.fetch(entry);\n  }\n  if (Array.isArray(entry)) {\n    for (const element of entry) {\n      _collectJS(element, xref, list, parents);\n    }\n  } else if (entry instanceof Dict) {\n    if (isName(entry.get(\"S\"), \"JavaScript\")) {\n      const js = entry.get(\"JS\");\n      let code;\n      if (js instanceof BaseStream) {\n        code = js.getString();\n      } else if (typeof js === \"string\") {\n        code = js;\n      }\n      code &&= stringToPDFString(code).replaceAll(\"\\x00\", \"\");\n      if (code) {\n        list.push(code);\n      }\n    }\n    _collectJS(entry.getRaw(\"Next\"), xref, list, parents);\n  }\n  if (parent) {\n    parents.remove(parent);\n  }\n}\nfunction collectActions(xref, dict, eventType) {\n  const actions = Object.create(null);\n  const additionalActionsDicts = getInheritableProperty({\n    dict,\n    key: \"AA\",\n    stopWhenFound: false\n  });\n  if (additionalActionsDicts) {\n    for (let i = additionalActionsDicts.length - 1; i >= 0; i--) {\n      const additionalActions = additionalActionsDicts[i];\n      if (!(additionalActions instanceof Dict)) {\n        continue;\n      }\n      for (const key of additionalActions.getKeys()) {\n        const action = eventType[key];\n        if (!action) {\n          continue;\n        }\n        const actionDict = additionalActions.getRaw(key);\n        const parents = new RefSet();\n        const list = [];\n        _collectJS(actionDict, xref, list, parents);\n        if (list.length > 0) {\n          actions[action] = list;\n        }\n      }\n    }\n  }\n  if (dict.has(\"A\")) {\n    const actionDict = dict.get(\"A\");\n    const parents = new RefSet();\n    const list = [];\n    _collectJS(actionDict, xref, list, parents);\n    if (list.length > 0) {\n      actions.Action = list;\n    }\n  }\n  return objectSize(actions) > 0 ? actions : null;\n}\nconst XMLEntities = {\n  0x3c: \"&lt;\",\n  0x3e: \"&gt;\",\n  0x26: \"&amp;\",\n  0x22: \"&quot;\",\n  0x27: \"&apos;\"\n};\nfunction* codePointIter(str) {\n  for (let i = 0, ii = str.length; i < ii; i++) {\n    const char = str.codePointAt(i);\n    if (char > 0xd7ff && (char < 0xe000 || char > 0xfffd)) {\n      i++;\n    }\n    yield char;\n  }\n}\nfunction encodeToXmlString(str) {\n  const buffer = [];\n  let start = 0;\n  for (let i = 0, ii = str.length; i < ii; i++) {\n    const char = str.codePointAt(i);\n    if (0x20 <= char && char <= 0x7e) {\n      const entity = XMLEntities[char];\n      if (entity) {\n        if (start < i) {\n          buffer.push(str.substring(start, i));\n        }\n        buffer.push(entity);\n        start = i + 1;\n      }\n    } else {\n      if (start < i) {\n        buffer.push(str.substring(start, i));\n      }\n      buffer.push(`&#x${char.toString(16).toUpperCase()};`);\n      if (char > 0xd7ff && (char < 0xe000 || char > 0xfffd)) {\n        i++;\n      }\n      start = i + 1;\n    }\n  }\n  if (buffer.length === 0) {\n    return str;\n  }\n  if (start < str.length) {\n    buffer.push(str.substring(start, str.length));\n  }\n  return buffer.join(\"\");\n}\nfunction validateFontName(fontFamily, mustWarn = false) {\n  const m = /^(\"|').*(\"|')$/.exec(fontFamily);\n  if (m && m[1] === m[2]) {\n    const re = new RegExp(`[^\\\\\\\\]${m[1]}`);\n    if (re.test(fontFamily.slice(1, -1))) {\n      if (mustWarn) {\n        warn(`FontFamily contains unescaped ${m[1]}: ${fontFamily}.`);\n      }\n      return false;\n    }\n  } else {\n    for (const ident of fontFamily.split(/[ \\t]+/)) {\n      if (/^(\\d|(-(\\d|-)))/.test(ident) || !/^[\\w-\\\\]+$/.test(ident)) {\n        if (mustWarn) {\n          warn(`FontFamily contains invalid <custom-ident>: ${fontFamily}.`);\n        }\n        return false;\n      }\n    }\n  }\n  return true;\n}\nfunction validateCSSFont(cssFontInfo) {\n  const DEFAULT_CSS_FONT_OBLIQUE = \"14\";\n  const DEFAULT_CSS_FONT_WEIGHT = \"400\";\n  const CSS_FONT_WEIGHT_VALUES = new Set([\"100\", \"200\", \"300\", \"400\", \"500\", \"600\", \"700\", \"800\", \"900\", \"1000\", \"normal\", \"bold\", \"bolder\", \"lighter\"]);\n  const {\n    fontFamily,\n    fontWeight,\n    italicAngle\n  } = cssFontInfo;\n  if (!validateFontName(fontFamily, true)) {\n    return false;\n  }\n  const weight = fontWeight ? fontWeight.toString() : \"\";\n  cssFontInfo.fontWeight = CSS_FONT_WEIGHT_VALUES.has(weight) ? weight : DEFAULT_CSS_FONT_WEIGHT;\n  const angle = parseFloat(italicAngle);\n  cssFontInfo.italicAngle = isNaN(angle) || angle < -90 || angle > 90 ? DEFAULT_CSS_FONT_OBLIQUE : italicAngle.toString();\n  return true;\n}\nfunction recoverJsURL(str) {\n  const URL_OPEN_METHODS = [\"app.launchURL\", \"window.open\", \"xfa.host.gotoURL\"];\n  const regex = new RegExp(\"^\\\\s*(\" + URL_OPEN_METHODS.join(\"|\").replaceAll(\".\", \"\\\\.\") + \")\\\\((?:'|\\\")([^'\\\"]*)(?:'|\\\")(?:,\\\\s*(\\\\w+)\\\\)|\\\\))\", \"i\");\n  const jsUrl = regex.exec(str);\n  if (jsUrl?.[2]) {\n    const url = jsUrl[2];\n    let newWindow = false;\n    if (jsUrl[3] === \"true\" && jsUrl[1] === \"app.launchURL\") {\n      newWindow = true;\n    }\n    return {\n      url,\n      newWindow\n    };\n  }\n  return null;\n}\nfunction numberToString(value) {\n  if (Number.isInteger(value)) {\n    return value.toString();\n  }\n  const roundedValue = Math.round(value * 100);\n  if (roundedValue % 100 === 0) {\n    return (roundedValue / 100).toString();\n  }\n  if (roundedValue % 10 === 0) {\n    return value.toFixed(1);\n  }\n  return value.toFixed(2);\n}\nfunction getNewAnnotationsMap(annotationStorage) {\n  if (!annotationStorage) {\n    return null;\n  }\n  const newAnnotationsByPage = new Map();\n  for (const [key, value] of annotationStorage) {\n    if (!key.startsWith(AnnotationEditorPrefix)) {\n      continue;\n    }\n    let annotations = newAnnotationsByPage.get(value.pageIndex);\n    if (!annotations) {\n      annotations = [];\n      newAnnotationsByPage.set(value.pageIndex, annotations);\n    }\n    annotations.push(value);\n  }\n  return newAnnotationsByPage.size > 0 ? newAnnotationsByPage : null;\n}\nfunction isAscii(str) {\n  return /^[\\x00-\\x7F]*$/.test(str);\n}\nfunction stringToUTF16HexString(str) {\n  const buf = [];\n  for (let i = 0, ii = str.length; i < ii; i++) {\n    const char = str.charCodeAt(i);\n    buf.push((char >> 8 & 0xff).toString(16).padStart(2, \"0\"), (char & 0xff).toString(16).padStart(2, \"0\"));\n  }\n  return buf.join(\"\");\n}\nfunction stringToUTF16String(str, bigEndian = false) {\n  const buf = [];\n  if (bigEndian) {\n    buf.push(\"\\xFE\\xFF\");\n  }\n  for (let i = 0, ii = str.length; i < ii; i++) {\n    const char = str.charCodeAt(i);\n    buf.push(String.fromCharCode(char >> 8 & 0xff), String.fromCharCode(char & 0xff));\n  }\n  return buf.join(\"\");\n}\nfunction getRotationMatrix(rotation, width, height) {\n  switch (rotation) {\n    case 90:\n      return [0, 1, -1, 0, width, 0];\n    case 180:\n      return [-1, 0, 0, -1, width, height];\n    case 270:\n      return [0, -1, 1, 0, 0, height];\n    default:\n      throw new Error(\"Invalid rotation\");\n  }\n}\nfunction getSizeInBytes(x) {\n  return Math.ceil(Math.ceil(Math.log2(1 + x)) / 8);\n}\n\n;// ./src/core/stream.js\n\n\nclass Stream extends BaseStream {\n  constructor(arrayBuffer, start, length, dict) {\n    super();\n    this.bytes = arrayBuffer instanceof Uint8Array ? arrayBuffer : new Uint8Array(arrayBuffer);\n    this.start = start || 0;\n    this.pos = this.start;\n    this.end = start + length || this.bytes.length;\n    this.dict = dict;\n  }\n  get length() {\n    return this.end - this.start;\n  }\n  get isEmpty() {\n    return this.length === 0;\n  }\n  getByte() {\n    if (this.pos >= this.end) {\n      return -1;\n    }\n    return this.bytes[this.pos++];\n  }\n  getBytes(length) {\n    const bytes = this.bytes;\n    const pos = this.pos;\n    const strEnd = this.end;\n    if (!length) {\n      return bytes.subarray(pos, strEnd);\n    }\n    let end = pos + length;\n    if (end > strEnd) {\n      end = strEnd;\n    }\n    this.pos = end;\n    return bytes.subarray(pos, end);\n  }\n  getByteRange(begin, end) {\n    if (begin < 0) {\n      begin = 0;\n    }\n    if (end > this.end) {\n      end = this.end;\n    }\n    return this.bytes.subarray(begin, end);\n  }\n  reset() {\n    this.pos = this.start;\n  }\n  moveStart() {\n    this.start = this.pos;\n  }\n  makeSubStream(start, length, dict = null) {\n    return new Stream(this.bytes.buffer, start, length, dict);\n  }\n}\nclass StringStream extends Stream {\n  constructor(str) {\n    super(stringToBytes(str));\n  }\n}\nclass NullStream extends Stream {\n  constructor() {\n    super(new Uint8Array(0));\n  }\n}\n\n;// ./src/core/chunked_stream.js\n\n\n\nclass ChunkedStream extends Stream {\n  constructor(length, chunkSize, manager) {\n    super(new Uint8Array(length), 0, length, null);\n    this.chunkSize = chunkSize;\n    this._loadedChunks = new Set();\n    this.numChunks = Math.ceil(length / chunkSize);\n    this.manager = manager;\n    this.progressiveDataLength = 0;\n    this.lastSuccessfulEnsureByteChunk = -1;\n  }\n  getMissingChunks() {\n    const chunks = [];\n    for (let chunk = 0, n = this.numChunks; chunk < n; ++chunk) {\n      if (!this._loadedChunks.has(chunk)) {\n        chunks.push(chunk);\n      }\n    }\n    return chunks;\n  }\n  get numChunksLoaded() {\n    return this._loadedChunks.size;\n  }\n  get isDataLoaded() {\n    return this.numChunksLoaded === this.numChunks;\n  }\n  onReceiveData(begin, chunk) {\n    const chunkSize = this.chunkSize;\n    if (begin % chunkSize !== 0) {\n      throw new Error(`Bad begin offset: ${begin}`);\n    }\n    const end = begin + chunk.byteLength;\n    if (end % chunkSize !== 0 && end !== this.bytes.length) {\n      throw new Error(`Bad end offset: ${end}`);\n    }\n    this.bytes.set(new Uint8Array(chunk), begin);\n    const beginChunk = Math.floor(begin / chunkSize);\n    const endChunk = Math.floor((end - 1) / chunkSize) + 1;\n    for (let curChunk = beginChunk; curChunk < endChunk; ++curChunk) {\n      this._loadedChunks.add(curChunk);\n    }\n  }\n  onReceiveProgressiveData(data) {\n    let position = this.progressiveDataLength;\n    const beginChunk = Math.floor(position / this.chunkSize);\n    this.bytes.set(new Uint8Array(data), position);\n    position += data.byteLength;\n    this.progressiveDataLength = position;\n    const endChunk = position >= this.end ? this.numChunks : Math.floor(position / this.chunkSize);\n    for (let curChunk = beginChunk; curChunk < endChunk; ++curChunk) {\n      this._loadedChunks.add(curChunk);\n    }\n  }\n  ensureByte(pos) {\n    if (pos < this.progressiveDataLength) {\n      return;\n    }\n    const chunk = Math.floor(pos / this.chunkSize);\n    if (chunk > this.numChunks) {\n      return;\n    }\n    if (chunk === this.lastSuccessfulEnsureByteChunk) {\n      return;\n    }\n    if (!this._loadedChunks.has(chunk)) {\n      throw new MissingDataException(pos, pos + 1);\n    }\n    this.lastSuccessfulEnsureByteChunk = chunk;\n  }\n  ensureRange(begin, end) {\n    if (begin >= end) {\n      return;\n    }\n    if (end <= this.progressiveDataLength) {\n      return;\n    }\n    const beginChunk = Math.floor(begin / this.chunkSize);\n    if (beginChunk > this.numChunks) {\n      return;\n    }\n    const endChunk = Math.min(Math.floor((end - 1) / this.chunkSize) + 1, this.numChunks);\n    for (let chunk = beginChunk; chunk < endChunk; ++chunk) {\n      if (!this._loadedChunks.has(chunk)) {\n        throw new MissingDataException(begin, end);\n      }\n    }\n  }\n  nextEmptyChunk(beginChunk) {\n    const numChunks = this.numChunks;\n    for (let i = 0; i < numChunks; ++i) {\n      const chunk = (beginChunk + i) % numChunks;\n      if (!this._loadedChunks.has(chunk)) {\n        return chunk;\n      }\n    }\n    return null;\n  }\n  hasChunk(chunk) {\n    return this._loadedChunks.has(chunk);\n  }\n  getByte() {\n    const pos = this.pos;\n    if (pos >= this.end) {\n      return -1;\n    }\n    if (pos >= this.progressiveDataLength) {\n      this.ensureByte(pos);\n    }\n    return this.bytes[this.pos++];\n  }\n  getBytes(length) {\n    const bytes = this.bytes;\n    const pos = this.pos;\n    const strEnd = this.end;\n    if (!length) {\n      if (strEnd > this.progressiveDataLength) {\n        this.ensureRange(pos, strEnd);\n      }\n      return bytes.subarray(pos, strEnd);\n    }\n    let end = pos + length;\n    if (end > strEnd) {\n      end = strEnd;\n    }\n    if (end > this.progressiveDataLength) {\n      this.ensureRange(pos, end);\n    }\n    this.pos = end;\n    return bytes.subarray(pos, end);\n  }\n  getByteRange(begin, end) {\n    if (begin < 0) {\n      begin = 0;\n    }\n    if (end > this.end) {\n      end = this.end;\n    }\n    if (end > this.progressiveDataLength) {\n      this.ensureRange(begin, end);\n    }\n    return this.bytes.subarray(begin, end);\n  }\n  makeSubStream(start, length, dict = null) {\n    if (length) {\n      if (start + length > this.progressiveDataLength) {\n        this.ensureRange(start, start + length);\n      }\n    } else if (start >= this.progressiveDataLength) {\n      this.ensureByte(start);\n    }\n    function ChunkedStreamSubstream() {}\n    ChunkedStreamSubstream.prototype = Object.create(this);\n    ChunkedStreamSubstream.prototype.getMissingChunks = function () {\n      const chunkSize = this.chunkSize;\n      const beginChunk = Math.floor(this.start / chunkSize);\n      const endChunk = Math.floor((this.end - 1) / chunkSize) + 1;\n      const missingChunks = [];\n      for (let chunk = beginChunk; chunk < endChunk; ++chunk) {\n        if (!this._loadedChunks.has(chunk)) {\n          missingChunks.push(chunk);\n        }\n      }\n      return missingChunks;\n    };\n    Object.defineProperty(ChunkedStreamSubstream.prototype, \"isDataLoaded\", {\n      get() {\n        if (this.numChunksLoaded === this.numChunks) {\n          return true;\n        }\n        return this.getMissingChunks().length === 0;\n      },\n      configurable: true\n    });\n    const subStream = new ChunkedStreamSubstream();\n    subStream.pos = subStream.start = start;\n    subStream.end = start + length || this.end;\n    subStream.dict = dict;\n    return subStream;\n  }\n  getBaseStreams() {\n    return [this];\n  }\n}\nclass ChunkedStreamManager {\n  constructor(pdfNetworkStream, args) {\n    this.length = args.length;\n    this.chunkSize = args.rangeChunkSize;\n    this.stream = new ChunkedStream(this.length, this.chunkSize, this);\n    this.pdfNetworkStream = pdfNetworkStream;\n    this.disableAutoFetch = args.disableAutoFetch;\n    this.msgHandler = args.msgHandler;\n    this.currRequestId = 0;\n    this._chunksNeededByRequest = new Map();\n    this._requestsByChunk = new Map();\n    this._promisesByRequest = new Map();\n    this.progressiveDataLength = 0;\n    this.aborted = false;\n    this._loadedStreamCapability = new PromiseCapability();\n  }\n  sendRequest(begin, end) {\n    const rangeReader = this.pdfNetworkStream.getRangeReader(begin, end);\n    if (!rangeReader.isStreamingSupported) {\n      rangeReader.onProgress = this.onProgress.bind(this);\n    }\n    let chunks = [],\n      loaded = 0;\n    return new Promise((resolve, reject) => {\n      const readChunk = ({\n        value,\n        done\n      }) => {\n        try {\n          if (done) {\n            const chunkData = arrayBuffersToBytes(chunks);\n            chunks = null;\n            resolve(chunkData);\n            return;\n          }\n          loaded += value.byteLength;\n          if (rangeReader.isStreamingSupported) {\n            this.onProgress({\n              loaded\n            });\n          }\n          chunks.push(value);\n          rangeReader.read().then(readChunk, reject);\n        } catch (e) {\n          reject(e);\n        }\n      };\n      rangeReader.read().then(readChunk, reject);\n    }).then(data => {\n      if (this.aborted) {\n        return;\n      }\n      this.onReceiveData({\n        chunk: data,\n        begin\n      });\n    });\n  }\n  requestAllChunks(noFetch = false) {\n    if (!noFetch) {\n      const missingChunks = this.stream.getMissingChunks();\n      this._requestChunks(missingChunks);\n    }\n    return this._loadedStreamCapability.promise;\n  }\n  _requestChunks(chunks) {\n    const requestId = this.currRequestId++;\n    const chunksNeeded = new Set();\n    this._chunksNeededByRequest.set(requestId, chunksNeeded);\n    for (const chunk of chunks) {\n      if (!this.stream.hasChunk(chunk)) {\n        chunksNeeded.add(chunk);\n      }\n    }\n    if (chunksNeeded.size === 0) {\n      return Promise.resolve();\n    }\n    const capability = new PromiseCapability();\n    this._promisesByRequest.set(requestId, capability);\n    const chunksToRequest = [];\n    for (const chunk of chunksNeeded) {\n      let requestIds = this._requestsByChunk.get(chunk);\n      if (!requestIds) {\n        requestIds = [];\n        this._requestsByChunk.set(chunk, requestIds);\n        chunksToRequest.push(chunk);\n      }\n      requestIds.push(requestId);\n    }\n    if (chunksToRequest.length > 0) {\n      const groupedChunksToRequest = this.groupChunks(chunksToRequest);\n      for (const groupedChunk of groupedChunksToRequest) {\n        const begin = groupedChunk.beginChunk * this.chunkSize;\n        const end = Math.min(groupedChunk.endChunk * this.chunkSize, this.length);\n        this.sendRequest(begin, end).catch(capability.reject);\n      }\n    }\n    return capability.promise.catch(reason => {\n      if (this.aborted) {\n        return;\n      }\n      throw reason;\n    });\n  }\n  getStream() {\n    return this.stream;\n  }\n  requestRange(begin, end) {\n    end = Math.min(end, this.length);\n    const beginChunk = this.getBeginChunk(begin);\n    const endChunk = this.getEndChunk(end);\n    const chunks = [];\n    for (let chunk = beginChunk; chunk < endChunk; ++chunk) {\n      chunks.push(chunk);\n    }\n    return this._requestChunks(chunks);\n  }\n  requestRanges(ranges = []) {\n    const chunksToRequest = [];\n    for (const range of ranges) {\n      const beginChunk = this.getBeginChunk(range.begin);\n      const endChunk = this.getEndChunk(range.end);\n      for (let chunk = beginChunk; chunk < endChunk; ++chunk) {\n        if (!chunksToRequest.includes(chunk)) {\n          chunksToRequest.push(chunk);\n        }\n      }\n    }\n    chunksToRequest.sort(function (a, b) {\n      return a - b;\n    });\n    return this._requestChunks(chunksToRequest);\n  }\n  groupChunks(chunks) {\n    const groupedChunks = [];\n    let beginChunk = -1;\n    let prevChunk = -1;\n    for (let i = 0, ii = chunks.length; i < ii; ++i) {\n      const chunk = chunks[i];\n      if (beginChunk < 0) {\n        beginChunk = chunk;\n      }\n      if (prevChunk >= 0 && prevChunk + 1 !== chunk) {\n        groupedChunks.push({\n          beginChunk,\n          endChunk: prevChunk + 1\n        });\n        beginChunk = chunk;\n      }\n      if (i + 1 === chunks.length) {\n        groupedChunks.push({\n          beginChunk,\n          endChunk: chunk + 1\n        });\n      }\n      prevChunk = chunk;\n    }\n    return groupedChunks;\n  }\n  onProgress(args) {\n    this.msgHandler.send(\"DocProgress\", {\n      loaded: this.stream.numChunksLoaded * this.chunkSize + args.loaded,\n      total: this.length\n    });\n  }\n  onReceiveData(args) {\n    const chunk = args.chunk;\n    const isProgressive = args.begin === undefined;\n    const begin = isProgressive ? this.progressiveDataLength : args.begin;\n    const end = begin + chunk.byteLength;\n    const beginChunk = Math.floor(begin / this.chunkSize);\n    const endChunk = end < this.length ? Math.floor(end / this.chunkSize) : Math.ceil(end / this.chunkSize);\n    if (isProgressive) {\n      this.stream.onReceiveProgressiveData(chunk);\n      this.progressiveDataLength = end;\n    } else {\n      this.stream.onReceiveData(begin, chunk);\n    }\n    if (this.stream.isDataLoaded) {\n      this._loadedStreamCapability.resolve(this.stream);\n    }\n    const loadedRequests = [];\n    for (let curChunk = beginChunk; curChunk < endChunk; ++curChunk) {\n      const requestIds = this._requestsByChunk.get(curChunk);\n      if (!requestIds) {\n        continue;\n      }\n      this._requestsByChunk.delete(curChunk);\n      for (const requestId of requestIds) {\n        const chunksNeeded = this._chunksNeededByRequest.get(requestId);\n        if (chunksNeeded.has(curChunk)) {\n          chunksNeeded.delete(curChunk);\n        }\n        if (chunksNeeded.size > 0) {\n          continue;\n        }\n        loadedRequests.push(requestId);\n      }\n    }\n    if (!this.disableAutoFetch && this._requestsByChunk.size === 0) {\n      let nextEmptyChunk;\n      if (this.stream.numChunksLoaded === 1) {\n        const lastChunk = this.stream.numChunks - 1;\n        if (!this.stream.hasChunk(lastChunk)) {\n          nextEmptyChunk = lastChunk;\n        }\n      } else {\n        nextEmptyChunk = this.stream.nextEmptyChunk(endChunk);\n      }\n      if (Number.isInteger(nextEmptyChunk)) {\n        this._requestChunks([nextEmptyChunk]);\n      }\n    }\n    for (const requestId of loadedRequests) {\n      const capability = this._promisesByRequest.get(requestId);\n      this._promisesByRequest.delete(requestId);\n      capability.resolve();\n    }\n    this.msgHandler.send(\"DocProgress\", {\n      loaded: this.stream.numChunksLoaded * this.chunkSize,\n      total: this.length\n    });\n  }\n  onError(err) {\n    this._loadedStreamCapability.reject(err);\n  }\n  getBeginChunk(begin) {\n    return Math.floor(begin / this.chunkSize);\n  }\n  getEndChunk(end) {\n    return Math.floor((end - 1) / this.chunkSize) + 1;\n  }\n  abort(reason) {\n    this.aborted = true;\n    this.pdfNetworkStream?.cancelAllRequests(reason);\n    for (const capability of this._promisesByRequest.values()) {\n      capability.reject(reason);\n    }\n  }\n}\n\n;// ./src/core/colorspace.js\n\n\n\n\nfunction resizeRgbImage(src, dest, w1, h1, w2, h2, alpha01) {\n  const COMPONENTS = 3;\n  alpha01 = alpha01 !== 1 ? 0 : alpha01;\n  const xRatio = w1 / w2;\n  const yRatio = h1 / h2;\n  let newIndex = 0,\n    oldIndex;\n  const xScaled = new Uint16Array(w2);\n  const w1Scanline = w1 * COMPONENTS;\n  for (let i = 0; i < w2; i++) {\n    xScaled[i] = Math.floor(i * xRatio) * COMPONENTS;\n  }\n  for (let i = 0; i < h2; i++) {\n    const py = Math.floor(i * yRatio) * w1Scanline;\n    for (let j = 0; j < w2; j++) {\n      oldIndex = py + xScaled[j];\n      dest[newIndex++] = src[oldIndex++];\n      dest[newIndex++] = src[oldIndex++];\n      dest[newIndex++] = src[oldIndex++];\n      newIndex += alpha01;\n    }\n  }\n}\nclass ColorSpace {\n  constructor(name, numComps) {\n    if (this.constructor === ColorSpace) {\n      unreachable(\"Cannot initialize ColorSpace.\");\n    }\n    this.name = name;\n    this.numComps = numComps;\n  }\n  getRgb(src, srcOffset) {\n    const rgb = new Uint8ClampedArray(3);\n    this.getRgbItem(src, srcOffset, rgb, 0);\n    return rgb;\n  }\n  getRgbItem(src, srcOffset, dest, destOffset) {\n    unreachable(\"Should not call ColorSpace.getRgbItem\");\n  }\n  getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {\n    unreachable(\"Should not call ColorSpace.getRgbBuffer\");\n  }\n  getOutputLength(inputLength, alpha01) {\n    unreachable(\"Should not call ColorSpace.getOutputLength\");\n  }\n  isPassthrough(bits) {\n    return false;\n  }\n  isDefaultDecode(decodeMap, bpc) {\n    return ColorSpace.isDefaultDecode(decodeMap, this.numComps);\n  }\n  fillRgb(dest, originalWidth, originalHeight, width, height, actualHeight, bpc, comps, alpha01) {\n    const count = originalWidth * originalHeight;\n    let rgbBuf = null;\n    const numComponentColors = 1 << bpc;\n    const needsResizing = originalHeight !== height || originalWidth !== width;\n    if (this.isPassthrough(bpc)) {\n      rgbBuf = comps;\n    } else if (this.numComps === 1 && count > numComponentColors && this.name !== \"DeviceGray\" && this.name !== \"DeviceRGB\") {\n      const allColors = bpc <= 8 ? new Uint8Array(numComponentColors) : new Uint16Array(numComponentColors);\n      for (let i = 0; i < numComponentColors; i++) {\n        allColors[i] = i;\n      }\n      const colorMap = new Uint8ClampedArray(numComponentColors * 3);\n      this.getRgbBuffer(allColors, 0, numComponentColors, colorMap, 0, bpc, 0);\n      if (!needsResizing) {\n        let destPos = 0;\n        for (let i = 0; i < count; ++i) {\n          const key = comps[i] * 3;\n          dest[destPos++] = colorMap[key];\n          dest[destPos++] = colorMap[key + 1];\n          dest[destPos++] = colorMap[key + 2];\n          destPos += alpha01;\n        }\n      } else {\n        rgbBuf = new Uint8Array(count * 3);\n        let rgbPos = 0;\n        for (let i = 0; i < count; ++i) {\n          const key = comps[i] * 3;\n          rgbBuf[rgbPos++] = colorMap[key];\n          rgbBuf[rgbPos++] = colorMap[key + 1];\n          rgbBuf[rgbPos++] = colorMap[key + 2];\n        }\n      }\n    } else if (!needsResizing) {\n      this.getRgbBuffer(comps, 0, width * actualHeight, dest, 0, bpc, alpha01);\n    } else {\n      rgbBuf = new Uint8ClampedArray(count * 3);\n      this.getRgbBuffer(comps, 0, count, rgbBuf, 0, bpc, 0);\n    }\n    if (rgbBuf) {\n      if (needsResizing) {\n        resizeRgbImage(rgbBuf, dest, originalWidth, originalHeight, width, height, alpha01);\n      } else {\n        let destPos = 0,\n          rgbPos = 0;\n        for (let i = 0, ii = width * actualHeight; i < ii; i++) {\n          dest[destPos++] = rgbBuf[rgbPos++];\n          dest[destPos++] = rgbBuf[rgbPos++];\n          dest[destPos++] = rgbBuf[rgbPos++];\n          destPos += alpha01;\n        }\n      }\n    }\n  }\n  get usesZeroToOneRange() {\n    return shadow(this, \"usesZeroToOneRange\", true);\n  }\n  static _cache(cacheKey, xref, localColorSpaceCache, parsedColorSpace) {\n    if (!localColorSpaceCache) {\n      throw new Error('ColorSpace._cache - expected \"localColorSpaceCache\" argument.');\n    }\n    if (!parsedColorSpace) {\n      throw new Error('ColorSpace._cache - expected \"parsedColorSpace\" argument.');\n    }\n    let csName, csRef;\n    if (cacheKey instanceof Ref) {\n      csRef = cacheKey;\n      cacheKey = xref.fetch(cacheKey);\n    }\n    if (cacheKey instanceof Name) {\n      csName = cacheKey.name;\n    }\n    if (csName || csRef) {\n      localColorSpaceCache.set(csName, csRef, parsedColorSpace);\n    }\n  }\n  static getCached(cacheKey, xref, localColorSpaceCache) {\n    if (!localColorSpaceCache) {\n      throw new Error('ColorSpace.getCached - expected \"localColorSpaceCache\" argument.');\n    }\n    if (cacheKey instanceof Ref) {\n      const localColorSpace = localColorSpaceCache.getByRef(cacheKey);\n      if (localColorSpace) {\n        return localColorSpace;\n      }\n      try {\n        cacheKey = xref.fetch(cacheKey);\n      } catch (ex) {\n        if (ex instanceof MissingDataException) {\n          throw ex;\n        }\n      }\n    }\n    if (cacheKey instanceof Name) {\n      const localColorSpace = localColorSpaceCache.getByName(cacheKey.name);\n      if (localColorSpace) {\n        return localColorSpace;\n      }\n    }\n    return null;\n  }\n  static async parseAsync({\n    cs,\n    xref,\n    resources = null,\n    pdfFunctionFactory,\n    localColorSpaceCache\n  }) {\n    const parsedColorSpace = this._parse(cs, xref, resources, pdfFunctionFactory);\n    this._cache(cs, xref, localColorSpaceCache, parsedColorSpace);\n    return parsedColorSpace;\n  }\n  static parse({\n    cs,\n    xref,\n    resources = null,\n    pdfFunctionFactory,\n    localColorSpaceCache\n  }) {\n    const cachedColorSpace = this.getCached(cs, xref, localColorSpaceCache);\n    if (cachedColorSpace) {\n      return cachedColorSpace;\n    }\n    const parsedColorSpace = this._parse(cs, xref, resources, pdfFunctionFactory);\n    this._cache(cs, xref, localColorSpaceCache, parsedColorSpace);\n    return parsedColorSpace;\n  }\n  static _parse(cs, xref, resources = null, pdfFunctionFactory) {\n    cs = xref.fetchIfRef(cs);\n    if (cs instanceof Name) {\n      switch (cs.name) {\n        case \"G\":\n        case \"DeviceGray\":\n          return this.singletons.gray;\n        case \"RGB\":\n        case \"DeviceRGB\":\n          return this.singletons.rgb;\n        case \"CMYK\":\n        case \"DeviceCMYK\":\n          return this.singletons.cmyk;\n        case \"Pattern\":\n          return new PatternCS(null);\n        default:\n          if (resources instanceof Dict) {\n            const colorSpaces = resources.get(\"ColorSpace\");\n            if (colorSpaces instanceof Dict) {\n              const resourcesCS = colorSpaces.get(cs.name);\n              if (resourcesCS) {\n                if (resourcesCS instanceof Name) {\n                  return this._parse(resourcesCS, xref, resources, pdfFunctionFactory);\n                }\n                cs = resourcesCS;\n                break;\n              }\n            }\n          }\n          throw new FormatError(`Unrecognized ColorSpace: ${cs.name}`);\n      }\n    }\n    if (Array.isArray(cs)) {\n      const mode = xref.fetchIfRef(cs[0]).name;\n      let params, numComps, baseCS, whitePoint, blackPoint, gamma;\n      switch (mode) {\n        case \"G\":\n        case \"DeviceGray\":\n          return this.singletons.gray;\n        case \"RGB\":\n        case \"DeviceRGB\":\n          return this.singletons.rgb;\n        case \"CMYK\":\n        case \"DeviceCMYK\":\n          return this.singletons.cmyk;\n        case \"CalGray\":\n          params = xref.fetchIfRef(cs[1]);\n          whitePoint = params.getArray(\"WhitePoint\");\n          blackPoint = params.getArray(\"BlackPoint\");\n          gamma = params.get(\"Gamma\");\n          return new CalGrayCS(whitePoint, blackPoint, gamma);\n        case \"CalRGB\":\n          params = xref.fetchIfRef(cs[1]);\n          whitePoint = params.getArray(\"WhitePoint\");\n          blackPoint = params.getArray(\"BlackPoint\");\n          gamma = params.getArray(\"Gamma\");\n          const matrix = params.getArray(\"Matrix\");\n          return new CalRGBCS(whitePoint, blackPoint, gamma, matrix);\n        case \"ICCBased\":\n          const stream = xref.fetchIfRef(cs[1]);\n          const dict = stream.dict;\n          numComps = dict.get(\"N\");\n          const alt = dict.get(\"Alternate\");\n          if (alt) {\n            const altCS = this._parse(alt, xref, resources, pdfFunctionFactory);\n            if (altCS.numComps === numComps) {\n              return altCS;\n            }\n            warn(\"ICCBased color space: Ignoring incorrect /Alternate entry.\");\n          }\n          if (numComps === 1) {\n            return this.singletons.gray;\n          } else if (numComps === 3) {\n            return this.singletons.rgb;\n          } else if (numComps === 4) {\n            return this.singletons.cmyk;\n          }\n          break;\n        case \"Pattern\":\n          baseCS = cs[1] || null;\n          if (baseCS) {\n            baseCS = this._parse(baseCS, xref, resources, pdfFunctionFactory);\n          }\n          return new PatternCS(baseCS);\n        case \"I\":\n        case \"Indexed\":\n          baseCS = this._parse(cs[1], xref, resources, pdfFunctionFactory);\n          const hiVal = xref.fetchIfRef(cs[2]) + 1;\n          const lookup = xref.fetchIfRef(cs[3]);\n          return new IndexedCS(baseCS, hiVal, lookup);\n        case \"Separation\":\n        case \"DeviceN\":\n          const name = xref.fetchIfRef(cs[1]);\n          numComps = Array.isArray(name) ? name.length : 1;\n          baseCS = this._parse(cs[2], xref, resources, pdfFunctionFactory);\n          const tintFn = pdfFunctionFactory.create(cs[3]);\n          return new AlternateCS(numComps, baseCS, tintFn);\n        case \"Lab\":\n          params = xref.fetchIfRef(cs[1]);\n          whitePoint = params.getArray(\"WhitePoint\");\n          blackPoint = params.getArray(\"BlackPoint\");\n          const range = params.getArray(\"Range\");\n          return new LabCS(whitePoint, blackPoint, range);\n        default:\n          throw new FormatError(`Unimplemented ColorSpace object: ${mode}`);\n      }\n    }\n    throw new FormatError(`Unrecognized ColorSpace object: ${cs}`);\n  }\n  static isDefaultDecode(decode, numComps) {\n    if (!Array.isArray(decode)) {\n      return true;\n    }\n    if (numComps * 2 !== decode.length) {\n      warn(\"The decode map is not the correct length\");\n      return true;\n    }\n    for (let i = 0, ii = decode.length; i < ii; i += 2) {\n      if (decode[i] !== 0 || decode[i + 1] !== 1) {\n        return false;\n      }\n    }\n    return true;\n  }\n  static get singletons() {\n    return shadow(this, \"singletons\", {\n      get gray() {\n        return shadow(this, \"gray\", new DeviceGrayCS());\n      },\n      get rgb() {\n        return shadow(this, \"rgb\", new DeviceRgbCS());\n      },\n      get cmyk() {\n        return shadow(this, \"cmyk\", new DeviceCmykCS());\n      }\n    });\n  }\n}\nclass AlternateCS extends ColorSpace {\n  constructor(numComps, base, tintFn) {\n    super(\"Alternate\", numComps);\n    this.base = base;\n    this.tintFn = tintFn;\n    this.tmpBuf = new Float32Array(base.numComps);\n  }\n  getRgbItem(src, srcOffset, dest, destOffset) {\n    const tmpBuf = this.tmpBuf;\n    this.tintFn(src, srcOffset, tmpBuf, 0);\n    this.base.getRgbItem(tmpBuf, 0, dest, destOffset);\n  }\n  getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {\n    const tintFn = this.tintFn;\n    const base = this.base;\n    const scale = 1 / ((1 << bits) - 1);\n    const baseNumComps = base.numComps;\n    const usesZeroToOneRange = base.usesZeroToOneRange;\n    const isPassthrough = (base.isPassthrough(8) || !usesZeroToOneRange) && alpha01 === 0;\n    let pos = isPassthrough ? destOffset : 0;\n    const baseBuf = isPassthrough ? dest : new Uint8ClampedArray(baseNumComps * count);\n    const numComps = this.numComps;\n    const scaled = new Float32Array(numComps);\n    const tinted = new Float32Array(baseNumComps);\n    let i, j;\n    for (i = 0; i < count; i++) {\n      for (j = 0; j < numComps; j++) {\n        scaled[j] = src[srcOffset++] * scale;\n      }\n      tintFn(scaled, 0, tinted, 0);\n      if (usesZeroToOneRange) {\n        for (j = 0; j < baseNumComps; j++) {\n          baseBuf[pos++] = tinted[j] * 255;\n        }\n      } else {\n        base.getRgbItem(tinted, 0, baseBuf, pos);\n        pos += baseNumComps;\n      }\n    }\n    if (!isPassthrough) {\n      base.getRgbBuffer(baseBuf, 0, count, dest, destOffset, 8, alpha01);\n    }\n  }\n  getOutputLength(inputLength, alpha01) {\n    return this.base.getOutputLength(inputLength * this.base.numComps / this.numComps, alpha01);\n  }\n}\nclass PatternCS extends ColorSpace {\n  constructor(baseCS) {\n    super(\"Pattern\", null);\n    this.base = baseCS;\n  }\n  isDefaultDecode(decodeMap, bpc) {\n    unreachable(\"Should not call PatternCS.isDefaultDecode\");\n  }\n}\nclass IndexedCS extends ColorSpace {\n  constructor(base, highVal, lookup) {\n    super(\"Indexed\", 1);\n    this.base = base;\n    this.highVal = highVal;\n    const length = base.numComps * highVal;\n    this.lookup = new Uint8Array(length);\n    if (lookup instanceof BaseStream) {\n      const bytes = lookup.getBytes(length);\n      this.lookup.set(bytes);\n    } else if (typeof lookup === \"string\") {\n      for (let i = 0; i < length; ++i) {\n        this.lookup[i] = lookup.charCodeAt(i) & 0xff;\n      }\n    } else {\n      throw new FormatError(`IndexedCS - unrecognized lookup table: ${lookup}`);\n    }\n  }\n  getRgbItem(src, srcOffset, dest, destOffset) {\n    const numComps = this.base.numComps;\n    const start = src[srcOffset] * numComps;\n    this.base.getRgbBuffer(this.lookup, start, 1, dest, destOffset, 8, 0);\n  }\n  getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {\n    const base = this.base;\n    const numComps = base.numComps;\n    const outputDelta = base.getOutputLength(numComps, alpha01);\n    const lookup = this.lookup;\n    for (let i = 0; i < count; ++i) {\n      const lookupPos = src[srcOffset++] * numComps;\n      base.getRgbBuffer(lookup, lookupPos, 1, dest, destOffset, 8, alpha01);\n      destOffset += outputDelta;\n    }\n  }\n  getOutputLength(inputLength, alpha01) {\n    return this.base.getOutputLength(inputLength * this.base.numComps, alpha01);\n  }\n  isDefaultDecode(decodeMap, bpc) {\n    if (!Array.isArray(decodeMap)) {\n      return true;\n    }\n    if (decodeMap.length !== 2) {\n      warn(\"Decode map length is not correct\");\n      return true;\n    }\n    if (!Number.isInteger(bpc) || bpc < 1) {\n      warn(\"Bits per component is not correct\");\n      return true;\n    }\n    return decodeMap[0] === 0 && decodeMap[1] === (1 << bpc) - 1;\n  }\n}\nclass DeviceGrayCS extends ColorSpace {\n  constructor() {\n    super(\"DeviceGray\", 1);\n  }\n  getRgbItem(src, srcOffset, dest, destOffset) {\n    const c = src[srcOffset] * 255;\n    dest[destOffset] = dest[destOffset + 1] = dest[destOffset + 2] = c;\n  }\n  getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {\n    const scale = 255 / ((1 << bits) - 1);\n    let j = srcOffset,\n      q = destOffset;\n    for (let i = 0; i < count; ++i) {\n      const c = scale * src[j++];\n      dest[q++] = c;\n      dest[q++] = c;\n      dest[q++] = c;\n      q += alpha01;\n    }\n  }\n  getOutputLength(inputLength, alpha01) {\n    return inputLength * (3 + alpha01);\n  }\n}\nclass DeviceRgbCS extends ColorSpace {\n  constructor() {\n    super(\"DeviceRGB\", 3);\n  }\n  getRgbItem(src, srcOffset, dest, destOffset) {\n    dest[destOffset] = src[srcOffset] * 255;\n    dest[destOffset + 1] = src[srcOffset + 1] * 255;\n    dest[destOffset + 2] = src[srcOffset + 2] * 255;\n  }\n  getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {\n    if (bits === 8 && alpha01 === 0) {\n      dest.set(src.subarray(srcOffset, srcOffset + count * 3), destOffset);\n      return;\n    }\n    const scale = 255 / ((1 << bits) - 1);\n    let j = srcOffset,\n      q = destOffset;\n    for (let i = 0; i < count; ++i) {\n      dest[q++] = scale * src[j++];\n      dest[q++] = scale * src[j++];\n      dest[q++] = scale * src[j++];\n      q += alpha01;\n    }\n  }\n  getOutputLength(inputLength, alpha01) {\n    return inputLength * (3 + alpha01) / 3 | 0;\n  }\n  isPassthrough(bits) {\n    return bits === 8;\n  }\n}\nclass DeviceCmykCS extends ColorSpace {\n  constructor() {\n    super(\"DeviceCMYK\", 4);\n  }\n  #toRgb(src, srcOffset, srcScale, dest, destOffset) {\n    const c = src[srcOffset] * srcScale;\n    const m = src[srcOffset + 1] * srcScale;\n    const y = src[srcOffset + 2] * srcScale;\n    const k = src[srcOffset + 3] * srcScale;\n    dest[destOffset] = 255 + c * (-4.387332384609988 * c + 54.48615194189176 * m + 18.82290502165302 * y + 212.25662451639585 * k + -285.2331026137004) + m * (1.7149763477362134 * m - 5.6096736904047315 * y + -17.873870861415444 * k - 5.497006427196366) + y * (-2.5217340131683033 * y - 21.248923337353073 * k + 17.5119270841813) + k * (-21.86122147463605 * k - 189.48180835922747);\n    dest[destOffset + 1] = 255 + c * (8.841041422036149 * c + 60.118027045597366 * m + 6.871425592049007 * y + 31.159100130055922 * k + -79.2970844816548) + m * (-15.310361306967817 * m + 17.575251261109482 * y + 131.35250912493976 * k - 190.9453302588951) + y * (4.444339102852739 * y + 9.8632861493405 * k - 24.86741582555878) + k * (-20.737325471181034 * k - 187.80453709719578);\n    dest[destOffset + 2] = 255 + c * (0.8842522430003296 * c + 8.078677503112928 * m + 30.89978309703729 * y - 0.23883238689178934 * k + -14.183576799673286) + m * (10.49593273432072 * m + 63.02378494754052 * y + 50.606957656360734 * k - 112.23884253719248) + y * (0.03296041114873217 * y + 115.60384449646641 * k + -193.58209356861505) + k * (-22.33816807309886 * k - 180.12613974708367);\n  }\n  getRgbItem(src, srcOffset, dest, destOffset) {\n    this.#toRgb(src, srcOffset, 1, dest, destOffset);\n  }\n  getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {\n    const scale = 1 / ((1 << bits) - 1);\n    for (let i = 0; i < count; i++) {\n      this.#toRgb(src, srcOffset, scale, dest, destOffset);\n      srcOffset += 4;\n      destOffset += 3 + alpha01;\n    }\n  }\n  getOutputLength(inputLength, alpha01) {\n    return inputLength / 4 * (3 + alpha01) | 0;\n  }\n}\nclass CalGrayCS extends ColorSpace {\n  constructor(whitePoint, blackPoint, gamma) {\n    super(\"CalGray\", 1);\n    if (!whitePoint) {\n      throw new FormatError(\"WhitePoint missing - required for color space CalGray\");\n    }\n    [this.XW, this.YW, this.ZW] = whitePoint;\n    [this.XB, this.YB, this.ZB] = blackPoint || [0, 0, 0];\n    this.G = gamma || 1;\n    if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) {\n      throw new FormatError(`Invalid WhitePoint components for ${this.name}, no fallback available`);\n    }\n    if (this.XB < 0 || this.YB < 0 || this.ZB < 0) {\n      info(`Invalid BlackPoint for ${this.name}, falling back to default.`);\n      this.XB = this.YB = this.ZB = 0;\n    }\n    if (this.XB !== 0 || this.YB !== 0 || this.ZB !== 0) {\n      warn(`${this.name}, BlackPoint: XB: ${this.XB}, YB: ${this.YB}, ` + `ZB: ${this.ZB}, only default values are supported.`);\n    }\n    if (this.G < 1) {\n      info(`Invalid Gamma: ${this.G} for ${this.name}, falling back to default.`);\n      this.G = 1;\n    }\n  }\n  #toRgb(src, srcOffset, dest, destOffset, scale) {\n    const A = src[srcOffset] * scale;\n    const AG = A ** this.G;\n    const L = this.YW * AG;\n    const val = Math.max(295.8 * L ** 0.3333333333333333 - 40.8, 0);\n    dest[destOffset] = val;\n    dest[destOffset + 1] = val;\n    dest[destOffset + 2] = val;\n  }\n  getRgbItem(src, srcOffset, dest, destOffset) {\n    this.#toRgb(src, srcOffset, dest, destOffset, 1);\n  }\n  getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {\n    const scale = 1 / ((1 << bits) - 1);\n    for (let i = 0; i < count; ++i) {\n      this.#toRgb(src, srcOffset, dest, destOffset, scale);\n      srcOffset += 1;\n      destOffset += 3 + alpha01;\n    }\n  }\n  getOutputLength(inputLength, alpha01) {\n    return inputLength * (3 + alpha01);\n  }\n}\nclass CalRGBCS extends ColorSpace {\n  static #BRADFORD_SCALE_MATRIX = new Float32Array([0.8951, 0.2664, -0.1614, -0.7502, 1.7135, 0.0367, 0.0389, -0.0685, 1.0296]);\n  static #BRADFORD_SCALE_INVERSE_MATRIX = new Float32Array([0.9869929, -0.1470543, 0.1599627, 0.4323053, 0.5183603, 0.0492912, -0.0085287, 0.0400428, 0.9684867]);\n  static #SRGB_D65_XYZ_TO_RGB_MATRIX = new Float32Array([3.2404542, -1.5371385, -0.4985314, -0.9692660, 1.8760108, 0.0415560, 0.0556434, -0.2040259, 1.0572252]);\n  static #FLAT_WHITEPOINT_MATRIX = new Float32Array([1, 1, 1]);\n  static #tempNormalizeMatrix = new Float32Array(3);\n  static #tempConvertMatrix1 = new Float32Array(3);\n  static #tempConvertMatrix2 = new Float32Array(3);\n  static #DECODE_L_CONSTANT = ((8 + 16) / 116) ** 3 / 8.0;\n  constructor(whitePoint, blackPoint, gamma, matrix) {\n    super(\"CalRGB\", 3);\n    if (!whitePoint) {\n      throw new FormatError(\"WhitePoint missing - required for color space CalRGB\");\n    }\n    const [XW, YW, ZW] = this.whitePoint = whitePoint;\n    const [XB, YB, ZB] = this.blackPoint = blackPoint || new Float32Array(3);\n    [this.GR, this.GG, this.GB] = gamma || new Float32Array([1, 1, 1]);\n    [this.MXA, this.MYA, this.MZA, this.MXB, this.MYB, this.MZB, this.MXC, this.MYC, this.MZC] = matrix || new Float32Array([1, 0, 0, 0, 1, 0, 0, 0, 1]);\n    if (XW < 0 || ZW < 0 || YW !== 1) {\n      throw new FormatError(`Invalid WhitePoint components for ${this.name}, no fallback available`);\n    }\n    if (XB < 0 || YB < 0 || ZB < 0) {\n      info(`Invalid BlackPoint for ${this.name} [${XB}, ${YB}, ${ZB}], ` + \"falling back to default.\");\n      this.blackPoint = new Float32Array(3);\n    }\n    if (this.GR < 0 || this.GG < 0 || this.GB < 0) {\n      info(`Invalid Gamma [${this.GR}, ${this.GG}, ${this.GB}] for ` + `${this.name}, falling back to default.`);\n      this.GR = this.GG = this.GB = 1;\n    }\n  }\n  #matrixProduct(a, b, result) {\n    result[0] = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];\n    result[1] = a[3] * b[0] + a[4] * b[1] + a[5] * b[2];\n    result[2] = a[6] * b[0] + a[7] * b[1] + a[8] * b[2];\n  }\n  #toFlat(sourceWhitePoint, LMS, result) {\n    result[0] = LMS[0] * 1 / sourceWhitePoint[0];\n    result[1] = LMS[1] * 1 / sourceWhitePoint[1];\n    result[2] = LMS[2] * 1 / sourceWhitePoint[2];\n  }\n  #toD65(sourceWhitePoint, LMS, result) {\n    const D65X = 0.95047;\n    const D65Y = 1;\n    const D65Z = 1.08883;\n    result[0] = LMS[0] * D65X / sourceWhitePoint[0];\n    result[1] = LMS[1] * D65Y / sourceWhitePoint[1];\n    result[2] = LMS[2] * D65Z / sourceWhitePoint[2];\n  }\n  #sRGBTransferFunction(color) {\n    if (color <= 0.0031308) {\n      return this.#adjustToRange(0, 1, 12.92 * color);\n    }\n    if (color >= 0.99554525) {\n      return 1;\n    }\n    return this.#adjustToRange(0, 1, (1 + 0.055) * color ** (1 / 2.4) - 0.055);\n  }\n  #adjustToRange(min, max, value) {\n    return Math.max(min, Math.min(max, value));\n  }\n  #decodeL(L) {\n    if (L < 0) {\n      return -this.#decodeL(-L);\n    }\n    if (L > 8.0) {\n      return ((L + 16) / 116) ** 3;\n    }\n    return L * CalRGBCS.#DECODE_L_CONSTANT;\n  }\n  #compensateBlackPoint(sourceBlackPoint, XYZ_Flat, result) {\n    if (sourceBlackPoint[0] === 0 && sourceBlackPoint[1] === 0 && sourceBlackPoint[2] === 0) {\n      result[0] = XYZ_Flat[0];\n      result[1] = XYZ_Flat[1];\n      result[2] = XYZ_Flat[2];\n      return;\n    }\n    const zeroDecodeL = this.#decodeL(0);\n    const X_DST = zeroDecodeL;\n    const X_SRC = this.#decodeL(sourceBlackPoint[0]);\n    const Y_DST = zeroDecodeL;\n    const Y_SRC = this.#decodeL(sourceBlackPoint[1]);\n    const Z_DST = zeroDecodeL;\n    const Z_SRC = this.#decodeL(sourceBlackPoint[2]);\n    const X_Scale = (1 - X_DST) / (1 - X_SRC);\n    const X_Offset = 1 - X_Scale;\n    const Y_Scale = (1 - Y_DST) / (1 - Y_SRC);\n    const Y_Offset = 1 - Y_Scale;\n    const Z_Scale = (1 - Z_DST) / (1 - Z_SRC);\n    const Z_Offset = 1 - Z_Scale;\n    result[0] = XYZ_Flat[0] * X_Scale + X_Offset;\n    result[1] = XYZ_Flat[1] * Y_Scale + Y_Offset;\n    result[2] = XYZ_Flat[2] * Z_Scale + Z_Offset;\n  }\n  #normalizeWhitePointToFlat(sourceWhitePoint, XYZ_In, result) {\n    if (sourceWhitePoint[0] === 1 && sourceWhitePoint[2] === 1) {\n      result[0] = XYZ_In[0];\n      result[1] = XYZ_In[1];\n      result[2] = XYZ_In[2];\n      return;\n    }\n    const LMS = result;\n    this.#matrixProduct(CalRGBCS.#BRADFORD_SCALE_MATRIX, XYZ_In, LMS);\n    const LMS_Flat = CalRGBCS.#tempNormalizeMatrix;\n    this.#toFlat(sourceWhitePoint, LMS, LMS_Flat);\n    this.#matrixProduct(CalRGBCS.#BRADFORD_SCALE_INVERSE_MATRIX, LMS_Flat, result);\n  }\n  #normalizeWhitePointToD65(sourceWhitePoint, XYZ_In, result) {\n    const LMS = result;\n    this.#matrixProduct(CalRGBCS.#BRADFORD_SCALE_MATRIX, XYZ_In, LMS);\n    const LMS_D65 = CalRGBCS.#tempNormalizeMatrix;\n    this.#toD65(sourceWhitePoint, LMS, LMS_D65);\n    this.#matrixProduct(CalRGBCS.#BRADFORD_SCALE_INVERSE_MATRIX, LMS_D65, result);\n  }\n  #toRgb(src, srcOffset, dest, destOffset, scale) {\n    const A = this.#adjustToRange(0, 1, src[srcOffset] * scale);\n    const B = this.#adjustToRange(0, 1, src[srcOffset + 1] * scale);\n    const C = this.#adjustToRange(0, 1, src[srcOffset + 2] * scale);\n    const AGR = A === 1 ? 1 : A ** this.GR;\n    const BGG = B === 1 ? 1 : B ** this.GG;\n    const CGB = C === 1 ? 1 : C ** this.GB;\n    const X = this.MXA * AGR + this.MXB * BGG + this.MXC * CGB;\n    const Y = this.MYA * AGR + this.MYB * BGG + this.MYC * CGB;\n    const Z = this.MZA * AGR + this.MZB * BGG + this.MZC * CGB;\n    const XYZ = CalRGBCS.#tempConvertMatrix1;\n    XYZ[0] = X;\n    XYZ[1] = Y;\n    XYZ[2] = Z;\n    const XYZ_Flat = CalRGBCS.#tempConvertMatrix2;\n    this.#normalizeWhitePointToFlat(this.whitePoint, XYZ, XYZ_Flat);\n    const XYZ_Black = CalRGBCS.#tempConvertMatrix1;\n    this.#compensateBlackPoint(this.blackPoint, XYZ_Flat, XYZ_Black);\n    const XYZ_D65 = CalRGBCS.#tempConvertMatrix2;\n    this.#normalizeWhitePointToD65(CalRGBCS.#FLAT_WHITEPOINT_MATRIX, XYZ_Black, XYZ_D65);\n    const SRGB = CalRGBCS.#tempConvertMatrix1;\n    this.#matrixProduct(CalRGBCS.#SRGB_D65_XYZ_TO_RGB_MATRIX, XYZ_D65, SRGB);\n    dest[destOffset] = this.#sRGBTransferFunction(SRGB[0]) * 255;\n    dest[destOffset + 1] = this.#sRGBTransferFunction(SRGB[1]) * 255;\n    dest[destOffset + 2] = this.#sRGBTransferFunction(SRGB[2]) * 255;\n  }\n  getRgbItem(src, srcOffset, dest, destOffset) {\n    this.#toRgb(src, srcOffset, dest, destOffset, 1);\n  }\n  getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {\n    const scale = 1 / ((1 << bits) - 1);\n    for (let i = 0; i < count; ++i) {\n      this.#toRgb(src, srcOffset, dest, destOffset, scale);\n      srcOffset += 3;\n      destOffset += 3 + alpha01;\n    }\n  }\n  getOutputLength(inputLength, alpha01) {\n    return inputLength * (3 + alpha01) / 3 | 0;\n  }\n}\nclass LabCS extends ColorSpace {\n  constructor(whitePoint, blackPoint, range) {\n    super(\"Lab\", 3);\n    if (!whitePoint) {\n      throw new FormatError(\"WhitePoint missing - required for color space Lab\");\n    }\n    [this.XW, this.YW, this.ZW] = whitePoint;\n    [this.amin, this.amax, this.bmin, this.bmax] = range || [-100, 100, -100, 100];\n    [this.XB, this.YB, this.ZB] = blackPoint || [0, 0, 0];\n    if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) {\n      throw new FormatError(\"Invalid WhitePoint components, no fallback available\");\n    }\n    if (this.XB < 0 || this.YB < 0 || this.ZB < 0) {\n      info(\"Invalid BlackPoint, falling back to default\");\n      this.XB = this.YB = this.ZB = 0;\n    }\n    if (this.amin > this.amax || this.bmin > this.bmax) {\n      info(\"Invalid Range, falling back to defaults\");\n      this.amin = -100;\n      this.amax = 100;\n      this.bmin = -100;\n      this.bmax = 100;\n    }\n  }\n  #fn_g(x) {\n    return x >= 6 / 29 ? x ** 3 : 108 / 841 * (x - 4 / 29);\n  }\n  #decode(value, high1, low2, high2) {\n    return low2 + value * (high2 - low2) / high1;\n  }\n  #toRgb(src, srcOffset, maxVal, dest, destOffset) {\n    let Ls = src[srcOffset];\n    let as = src[srcOffset + 1];\n    let bs = src[srcOffset + 2];\n    if (maxVal !== false) {\n      Ls = this.#decode(Ls, maxVal, 0, 100);\n      as = this.#decode(as, maxVal, this.amin, this.amax);\n      bs = this.#decode(bs, maxVal, this.bmin, this.bmax);\n    }\n    if (as > this.amax) {\n      as = this.amax;\n    } else if (as < this.amin) {\n      as = this.amin;\n    }\n    if (bs > this.bmax) {\n      bs = this.bmax;\n    } else if (bs < this.bmin) {\n      bs = this.bmin;\n    }\n    const M = (Ls + 16) / 116;\n    const L = M + as / 500;\n    const N = M - bs / 200;\n    const X = this.XW * this.#fn_g(L);\n    const Y = this.YW * this.#fn_g(M);\n    const Z = this.ZW * this.#fn_g(N);\n    let r, g, b;\n    if (this.ZW < 1) {\n      r = X * 3.1339 + Y * -1.617 + Z * -0.4906;\n      g = X * -0.9785 + Y * 1.916 + Z * 0.0333;\n      b = X * 0.072 + Y * -0.229 + Z * 1.4057;\n    } else {\n      r = X * 3.2406 + Y * -1.5372 + Z * -0.4986;\n      g = X * -0.9689 + Y * 1.8758 + Z * 0.0415;\n      b = X * 0.0557 + Y * -0.204 + Z * 1.057;\n    }\n    dest[destOffset] = Math.sqrt(r) * 255;\n    dest[destOffset + 1] = Math.sqrt(g) * 255;\n    dest[destOffset + 2] = Math.sqrt(b) * 255;\n  }\n  getRgbItem(src, srcOffset, dest, destOffset) {\n    this.#toRgb(src, srcOffset, false, dest, destOffset);\n  }\n  getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {\n    const maxVal = (1 << bits) - 1;\n    for (let i = 0; i < count; i++) {\n      this.#toRgb(src, srcOffset, maxVal, dest, destOffset);\n      srcOffset += 3;\n      destOffset += 3 + alpha01;\n    }\n  }\n  getOutputLength(inputLength, alpha01) {\n    return inputLength * (3 + alpha01) / 3 | 0;\n  }\n  isDefaultDecode(decodeMap, bpc) {\n    return true;\n  }\n  get usesZeroToOneRange() {\n    return shadow(this, \"usesZeroToOneRange\", false);\n  }\n}\n\n;// external \"fs/promises\"\nconst promises_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)(\"fs/promises\");\n;// ./src/core/binary_cmap.js\n\nfunction hexToInt(a, size) {\n  let n = 0;\n  for (let i = 0; i <= size; i++) {\n    n = n << 8 | a[i];\n  }\n  return n >>> 0;\n}\nfunction hexToStr(a, size) {\n  if (size === 1) {\n    return String.fromCharCode(a[0], a[1]);\n  }\n  if (size === 3) {\n    return String.fromCharCode(a[0], a[1], a[2], a[3]);\n  }\n  return String.fromCharCode(...a.subarray(0, size + 1));\n}\nfunction addHex(a, b, size) {\n  let c = 0;\n  for (let i = size; i >= 0; i--) {\n    c += a[i] + b[i];\n    a[i] = c & 255;\n    c >>= 8;\n  }\n}\nfunction incHex(a, size) {\n  let c = 1;\n  for (let i = size; i >= 0 && c > 0; i--) {\n    c += a[i];\n    a[i] = c & 255;\n    c >>= 8;\n  }\n}\nconst MAX_NUM_SIZE = 16;\nconst MAX_ENCODED_NUM_SIZE = 19;\nclass BinaryCMapStream {\n  constructor(data) {\n    this.buffer = data;\n    this.pos = 0;\n    this.end = data.length;\n    this.tmpBuf = new Uint8Array(MAX_ENCODED_NUM_SIZE);\n  }\n  readByte() {\n    if (this.pos >= this.end) {\n      return -1;\n    }\n    return this.buffer[this.pos++];\n  }\n  readNumber() {\n    let n = 0;\n    let last;\n    do {\n      const b = this.readByte();\n      if (b < 0) {\n        throw new FormatError(\"unexpected EOF in bcmap\");\n      }\n      last = !(b & 0x80);\n      n = n << 7 | b & 0x7f;\n    } while (!last);\n    return n;\n  }\n  readSigned() {\n    const n = this.readNumber();\n    return n & 1 ? ~(n >>> 1) : n >>> 1;\n  }\n  readHex(num, size) {\n    num.set(this.buffer.subarray(this.pos, this.pos + size + 1));\n    this.pos += size + 1;\n  }\n  readHexNumber(num, size) {\n    let last;\n    const stack = this.tmpBuf;\n    let sp = 0;\n    do {\n      const b = this.readByte();\n      if (b < 0) {\n        throw new FormatError(\"unexpected EOF in bcmap\");\n      }\n      last = !(b & 0x80);\n      stack[sp++] = b & 0x7f;\n    } while (!last);\n    let i = size,\n      buffer = 0,\n      bufferSize = 0;\n    while (i >= 0) {\n      while (bufferSize < 8 && stack.length > 0) {\n        buffer |= stack[--sp] << bufferSize;\n        bufferSize += 7;\n      }\n      num[i] = buffer & 255;\n      i--;\n      buffer >>= 8;\n      bufferSize -= 8;\n    }\n  }\n  readHexSigned(num, size) {\n    this.readHexNumber(num, size);\n    const sign = num[size] & 1 ? 255 : 0;\n    let c = 0;\n    for (let i = 0; i <= size; i++) {\n      c = (c & 1) << 8 | num[i];\n      num[i] = c >> 1 ^ sign;\n    }\n  }\n  readString() {\n    const len = this.readNumber(),\n      buf = new Array(len);\n    for (let i = 0; i < len; i++) {\n      buf[i] = this.readNumber();\n    }\n    return String.fromCharCode(...buf);\n  }\n}\nclass BinaryCMapReader {\n  async process(data, cMap, extend) {\n    const stream = new BinaryCMapStream(data);\n    const header = stream.readByte();\n    cMap.vertical = !!(header & 1);\n    let useCMap = null;\n    const start = new Uint8Array(MAX_NUM_SIZE);\n    const end = new Uint8Array(MAX_NUM_SIZE);\n    const char = new Uint8Array(MAX_NUM_SIZE);\n    const charCode = new Uint8Array(MAX_NUM_SIZE);\n    const tmp = new Uint8Array(MAX_NUM_SIZE);\n    let code;\n    let b;\n    while ((b = stream.readByte()) >= 0) {\n      const type = b >> 5;\n      if (type === 7) {\n        switch (b & 0x1f) {\n          case 0:\n            stream.readString();\n            break;\n          case 1:\n            useCMap = stream.readString();\n            break;\n        }\n        continue;\n      }\n      const sequence = !!(b & 0x10);\n      const dataSize = b & 15;\n      if (dataSize + 1 > MAX_NUM_SIZE) {\n        throw new Error(\"BinaryCMapReader.process: Invalid dataSize.\");\n      }\n      const ucs2DataSize = 1;\n      const subitemsCount = stream.readNumber();\n      switch (type) {\n        case 0:\n          stream.readHex(start, dataSize);\n          stream.readHexNumber(end, dataSize);\n          addHex(end, start, dataSize);\n          cMap.addCodespaceRange(dataSize + 1, hexToInt(start, dataSize), hexToInt(end, dataSize));\n          for (let i = 1; i < subitemsCount; i++) {\n            incHex(end, dataSize);\n            stream.readHexNumber(start, dataSize);\n            addHex(start, end, dataSize);\n            stream.readHexNumber(end, dataSize);\n            addHex(end, start, dataSize);\n            cMap.addCodespaceRange(dataSize + 1, hexToInt(start, dataSize), hexToInt(end, dataSize));\n          }\n          break;\n        case 1:\n          stream.readHex(start, dataSize);\n          stream.readHexNumber(end, dataSize);\n          addHex(end, start, dataSize);\n          stream.readNumber();\n          for (let i = 1; i < subitemsCount; i++) {\n            incHex(end, dataSize);\n            stream.readHexNumber(start, dataSize);\n            addHex(start, end, dataSize);\n            stream.readHexNumber(end, dataSize);\n            addHex(end, start, dataSize);\n            stream.readNumber();\n          }\n          break;\n        case 2:\n          stream.readHex(char, dataSize);\n          code = stream.readNumber();\n          cMap.mapOne(hexToInt(char, dataSize), code);\n          for (let i = 1; i < subitemsCount; i++) {\n            incHex(char, dataSize);\n            if (!sequence) {\n              stream.readHexNumber(tmp, dataSize);\n              addHex(char, tmp, dataSize);\n            }\n            code = stream.readSigned() + (code + 1);\n            cMap.mapOne(hexToInt(char, dataSize), code);\n          }\n          break;\n        case 3:\n          stream.readHex(start, dataSize);\n          stream.readHexNumber(end, dataSize);\n          addHex(end, start, dataSize);\n          code = stream.readNumber();\n          cMap.mapCidRange(hexToInt(start, dataSize), hexToInt(end, dataSize), code);\n          for (let i = 1; i < subitemsCount; i++) {\n            incHex(end, dataSize);\n            if (!sequence) {\n              stream.readHexNumber(start, dataSize);\n              addHex(start, end, dataSize);\n            } else {\n              start.set(end);\n            }\n            stream.readHexNumber(end, dataSize);\n            addHex(end, start, dataSize);\n            code = stream.readNumber();\n            cMap.mapCidRange(hexToInt(start, dataSize), hexToInt(end, dataSize), code);\n          }\n          break;\n        case 4:\n          stream.readHex(char, ucs2DataSize);\n          stream.readHex(charCode, dataSize);\n          cMap.mapOne(hexToInt(char, ucs2DataSize), hexToStr(charCode, dataSize));\n          for (let i = 1; i < subitemsCount; i++) {\n            incHex(char, ucs2DataSize);\n            if (!sequence) {\n              stream.readHexNumber(tmp, ucs2DataSize);\n              addHex(char, tmp, ucs2DataSize);\n            }\n            incHex(charCode, dataSize);\n            stream.readHexSigned(tmp, dataSize);\n            addHex(charCode, tmp, dataSize);\n            cMap.mapOne(hexToInt(char, ucs2DataSize), hexToStr(charCode, dataSize));\n          }\n          break;\n        case 5:\n          stream.readHex(start, ucs2DataSize);\n          stream.readHexNumber(end, ucs2DataSize);\n          addHex(end, start, ucs2DataSize);\n          stream.readHex(charCode, dataSize);\n          cMap.mapBfRange(hexToInt(start, ucs2DataSize), hexToInt(end, ucs2DataSize), hexToStr(charCode, dataSize));\n          for (let i = 1; i < subitemsCount; i++) {\n            incHex(end, ucs2DataSize);\n            if (!sequence) {\n              stream.readHexNumber(start, ucs2DataSize);\n              addHex(start, end, ucs2DataSize);\n            } else {\n              start.set(end);\n            }\n            stream.readHexNumber(end, ucs2DataSize);\n            addHex(end, start, ucs2DataSize);\n            stream.readHex(charCode, dataSize);\n            cMap.mapBfRange(hexToInt(start, ucs2DataSize), hexToInt(end, ucs2DataSize), hexToStr(charCode, dataSize));\n          }\n          break;\n        default:\n          throw new Error(`BinaryCMapReader.process - unknown type: ${type}`);\n      }\n    }\n    if (useCMap) {\n      return extend(useCMap);\n    }\n    return cMap;\n  }\n}\n\n;// ./src/core/decode_stream.js\n\n\nconst emptyBuffer = new Uint8Array(0);\nclass DecodeStream extends BaseStream {\n  constructor(maybeMinBufferLength) {\n    super();\n    this._rawMinBufferLength = maybeMinBufferLength || 0;\n    this.pos = 0;\n    this.bufferLength = 0;\n    this.eof = false;\n    this.buffer = emptyBuffer;\n    this.minBufferLength = 512;\n    if (maybeMinBufferLength) {\n      while (this.minBufferLength < maybeMinBufferLength) {\n        this.minBufferLength *= 2;\n      }\n    }\n  }\n  get isEmpty() {\n    while (!this.eof && this.bufferLength === 0) {\n      this.readBlock();\n    }\n    return this.bufferLength === 0;\n  }\n  ensureBuffer(requested) {\n    const buffer = this.buffer;\n    if (requested <= buffer.byteLength) {\n      return buffer;\n    }\n    let size = this.minBufferLength;\n    while (size < requested) {\n      size *= 2;\n    }\n    const buffer2 = new Uint8Array(size);\n    buffer2.set(buffer);\n    return this.buffer = buffer2;\n  }\n  getByte() {\n    const pos = this.pos;\n    while (this.bufferLength <= pos) {\n      if (this.eof) {\n        return -1;\n      }\n      this.readBlock();\n    }\n    return this.buffer[this.pos++];\n  }\n  getBytes(length, ignoreColorSpace = false) {\n    const pos = this.pos;\n    let end;\n    if (length) {\n      this.ensureBuffer(pos + length);\n      end = pos + length;\n      while (!this.eof && this.bufferLength < end) {\n        this.readBlock(ignoreColorSpace);\n      }\n      const bufEnd = this.bufferLength;\n      if (end > bufEnd) {\n        end = bufEnd;\n      }\n    } else {\n      while (!this.eof) {\n        this.readBlock(ignoreColorSpace);\n      }\n      end = this.bufferLength;\n    }\n    this.pos = end;\n    return this.buffer.subarray(pos, end);\n  }\n  reset() {\n    this.pos = 0;\n  }\n  makeSubStream(start, length, dict = null) {\n    if (length === undefined) {\n      while (!this.eof) {\n        this.readBlock();\n      }\n    } else {\n      const end = start + length;\n      while (this.bufferLength <= end && !this.eof) {\n        this.readBlock();\n      }\n    }\n    return new Stream(this.buffer, start, length, dict);\n  }\n  getBaseStreams() {\n    return this.str ? this.str.getBaseStreams() : null;\n  }\n}\nclass StreamsSequenceStream extends DecodeStream {\n  constructor(streams, onError = null) {\n    let maybeLength = 0;\n    for (const stream of streams) {\n      maybeLength += stream instanceof DecodeStream ? stream._rawMinBufferLength : stream.length;\n    }\n    super(maybeLength);\n    this.streams = streams;\n    this._onError = onError;\n  }\n  readBlock() {\n    const streams = this.streams;\n    if (streams.length === 0) {\n      this.eof = true;\n      return;\n    }\n    const stream = streams.shift();\n    let chunk;\n    try {\n      chunk = stream.getBytes();\n    } catch (reason) {\n      if (this._onError) {\n        this._onError(reason, stream.dict?.objId);\n        return;\n      }\n      throw reason;\n    }\n    const bufferLength = this.bufferLength;\n    const newLength = bufferLength + chunk.length;\n    const buffer = this.ensureBuffer(newLength);\n    buffer.set(chunk, bufferLength);\n    this.bufferLength = newLength;\n  }\n  getBaseStreams() {\n    const baseStreamsBuf = [];\n    for (const stream of this.streams) {\n      const baseStreams = stream.getBaseStreams();\n      if (baseStreams) {\n        baseStreamsBuf.push(...baseStreams);\n      }\n    }\n    return baseStreamsBuf.length > 0 ? baseStreamsBuf : null;\n  }\n}\n\n;// ./src/core/ascii_85_stream.js\n\n\nclass Ascii85Stream extends DecodeStream {\n  constructor(str, maybeLength) {\n    if (maybeLength) {\n      maybeLength *= 0.8;\n    }\n    super(maybeLength);\n    this.str = str;\n    this.dict = str.dict;\n    this.input = new Uint8Array(5);\n  }\n  readBlock() {\n    const TILDA_CHAR = 0x7e;\n    const Z_LOWER_CHAR = 0x7a;\n    const EOF = -1;\n    const str = this.str;\n    let c = str.getByte();\n    while (isWhiteSpace(c)) {\n      c = str.getByte();\n    }\n    if (c === EOF || c === TILDA_CHAR) {\n      this.eof = true;\n      return;\n    }\n    const bufferLength = this.bufferLength;\n    let buffer, i;\n    if (c === Z_LOWER_CHAR) {\n      buffer = this.ensureBuffer(bufferLength + 4);\n      for (i = 0; i < 4; ++i) {\n        buffer[bufferLength + i] = 0;\n      }\n      this.bufferLength += 4;\n    } else {\n      const input = this.input;\n      input[0] = c;\n      for (i = 1; i < 5; ++i) {\n        c = str.getByte();\n        while (isWhiteSpace(c)) {\n          c = str.getByte();\n        }\n        input[i] = c;\n        if (c === EOF || c === TILDA_CHAR) {\n          break;\n        }\n      }\n      buffer = this.ensureBuffer(bufferLength + i - 1);\n      this.bufferLength += i - 1;\n      if (i < 5) {\n        for (; i < 5; ++i) {\n          input[i] = 0x21 + 84;\n        }\n        this.eof = true;\n      }\n      let t = 0;\n      for (i = 0; i < 5; ++i) {\n        t = t * 85 + (input[i] - 0x21);\n      }\n      for (i = 3; i >= 0; --i) {\n        buffer[bufferLength + i] = t & 0xff;\n        t >>= 8;\n      }\n    }\n  }\n}\n\n;// ./src/core/ascii_hex_stream.js\n\nclass AsciiHexStream extends DecodeStream {\n  constructor(str, maybeLength) {\n    if (maybeLength) {\n      maybeLength *= 0.5;\n    }\n    super(maybeLength);\n    this.str = str;\n    this.dict = str.dict;\n    this.firstDigit = -1;\n  }\n  readBlock() {\n    const UPSTREAM_BLOCK_SIZE = 8000;\n    const bytes = this.str.getBytes(UPSTREAM_BLOCK_SIZE);\n    if (!bytes.length) {\n      this.eof = true;\n      return;\n    }\n    const maxDecodeLength = bytes.length + 1 >> 1;\n    const buffer = this.ensureBuffer(this.bufferLength + maxDecodeLength);\n    let bufferLength = this.bufferLength;\n    let firstDigit = this.firstDigit;\n    for (const ch of bytes) {\n      let digit;\n      if (ch >= 0x30 && ch <= 0x39) {\n        digit = ch & 0x0f;\n      } else if (ch >= 0x41 && ch <= 0x46 || ch >= 0x61 && ch <= 0x66) {\n        digit = (ch & 0x0f) + 9;\n      } else if (ch === 0x3e) {\n        this.eof = true;\n        break;\n      } else {\n        continue;\n      }\n      if (firstDigit < 0) {\n        firstDigit = digit;\n      } else {\n        buffer[bufferLength++] = firstDigit << 4 | digit;\n        firstDigit = -1;\n      }\n    }\n    if (firstDigit >= 0 && this.eof) {\n      buffer[bufferLength++] = firstDigit << 4;\n      firstDigit = -1;\n    }\n    this.firstDigit = firstDigit;\n    this.bufferLength = bufferLength;\n  }\n}\n\n;// ./src/core/ccitt.js\n\nconst MAX_UINT_32 = 2 ** 32 - 1;\nconst ccittEOL = -2;\nconst ccittEOF = -1;\nconst twoDimPass = 0;\nconst twoDimHoriz = 1;\nconst twoDimVert0 = 2;\nconst twoDimVertR1 = 3;\nconst twoDimVertL1 = 4;\nconst twoDimVertR2 = 5;\nconst twoDimVertL2 = 6;\nconst twoDimVertR3 = 7;\nconst twoDimVertL3 = 8;\nconst twoDimTable = [[-1, -1], [-1, -1], [7, twoDimVertL3], [7, twoDimVertR3], [6, twoDimVertL2], [6, twoDimVertL2], [6, twoDimVertR2], [6, twoDimVertR2], [4, twoDimPass], [4, twoDimPass], [4, twoDimPass], [4, twoDimPass], [4, twoDimPass], [4, twoDimPass], [4, twoDimPass], [4, twoDimPass], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0]];\nconst whiteTable1 = [[-1, -1], [12, ccittEOL], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [11, 1792], [11, 1792], [12, 1984], [12, 2048], [12, 2112], [12, 2176], [12, 2240], [12, 2304], [11, 1856], [11, 1856], [11, 1920], [11, 1920], [12, 2368], [12, 2432], [12, 2496], [12, 2560]];\nconst whiteTable2 = [[-1, -1], [-1, -1], [-1, -1], [-1, -1], [8, 29], [8, 29], [8, 30], [8, 30], [8, 45], [8, 45], [8, 46], [8, 46], [7, 22], [7, 22], [7, 22], [7, 22], [7, 23], [7, 23], [7, 23], [7, 23], [8, 47], [8, 47], [8, 48], [8, 48], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [7, 20], [7, 20], [7, 20], [7, 20], [8, 33], [8, 33], [8, 34], [8, 34], [8, 35], [8, 35], [8, 36], [8, 36], [8, 37], [8, 37], [8, 38], [8, 38], [7, 19], [7, 19], [7, 19], [7, 19], [8, 31], [8, 31], [8, 32], [8, 32], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [8, 53], [8, 53], [8, 54], [8, 54], [7, 26], [7, 26], [7, 26], [7, 26], [8, 39], [8, 39], [8, 40], [8, 40], [8, 41], [8, 41], [8, 42], [8, 42], [8, 43], [8, 43], [8, 44], [8, 44], [7, 21], [7, 21], [7, 21], [7, 21], [7, 28], [7, 28], [7, 28], [7, 28], [8, 61], [8, 61], [8, 62], [8, 62], [8, 63], [8, 63], [8, 0], [8, 0], [8, 320], [8, 320], [8, 384], [8, 384], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [7, 27], [7, 27], [7, 27], [7, 27], [8, 59], [8, 59], [8, 60], [8, 60], [9, 1472], [9, 1536], [9, 1600], [9, 1728], [7, 18], [7, 18], [7, 18], [7, 18], [7, 24], [7, 24], [7, 24], [7, 24], [8, 49], [8, 49], [8, 50], [8, 50], [8, 51], [8, 51], [8, 52], [8, 52], [7, 25], [7, 25], [7, 25], [7, 25], [8, 55], [8, 55], [8, 56], [8, 56], [8, 57], [8, 57], [8, 58], [8, 58], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [8, 448], [8, 448], [8, 512], [8, 512], [9, 704], [9, 768], [8, 640], [8, 640], [8, 576], [8, 576], [9, 832], [9, 896], [9, 960], [9, 1024], [9, 1088], [9, 1152], [9, 1216], [9, 1280], [9, 1344], [9, 1408], [7, 256], [7, 256], [7, 256], [7, 256], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7]];\nconst blackTable1 = [[-1, -1], [-1, -1], [12, ccittEOL], [12, ccittEOL], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [11, 1792], [11, 1792], [11, 1792], [11, 1792], [12, 1984], [12, 1984], [12, 2048], [12, 2048], [12, 2112], [12, 2112], [12, 2176], [12, 2176], [12, 2240], [12, 2240], [12, 2304], [12, 2304], [11, 1856], [11, 1856], [11, 1856], [11, 1856], [11, 1920], [11, 1920], [11, 1920], [11, 1920], [12, 2368], [12, 2368], [12, 2432], [12, 2432], [12, 2496], [12, 2496], [12, 2560], [12, 2560], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [12, 52], [12, 52], [13, 640], [13, 704], [13, 768], [13, 832], [12, 55], [12, 55], [12, 56], [12, 56], [13, 1280], [13, 1344], [13, 1408], [13, 1472], [12, 59], [12, 59], [12, 60], [12, 60], [13, 1536], [13, 1600], [11, 24], [11, 24], [11, 24], [11, 24], [11, 25], [11, 25], [11, 25], [11, 25], [13, 1664], [13, 1728], [12, 320], [12, 320], [12, 384], [12, 384], [12, 448], [12, 448], [13, 512], [13, 576], [12, 53], [12, 53], [12, 54], [12, 54], [13, 896], [13, 960], [13, 1024], [13, 1088], [13, 1152], [13, 1216], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64]];\nconst blackTable2 = [[8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [11, 23], [11, 23], [12, 50], [12, 51], [12, 44], [12, 45], [12, 46], [12, 47], [12, 57], [12, 58], [12, 61], [12, 256], [10, 16], [10, 16], [10, 16], [10, 16], [10, 17], [10, 17], [10, 17], [10, 17], [12, 48], [12, 49], [12, 62], [12, 63], [12, 30], [12, 31], [12, 32], [12, 33], [12, 40], [12, 41], [11, 22], [11, 22], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [12, 128], [12, 192], [12, 26], [12, 27], [12, 28], [12, 29], [11, 19], [11, 19], [11, 20], [11, 20], [12, 34], [12, 35], [12, 36], [12, 37], [12, 38], [12, 39], [11, 21], [11, 21], [12, 42], [12, 43], [10, 0], [10, 0], [10, 0], [10, 0], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12]];\nconst blackTable3 = [[-1, -1], [-1, -1], [-1, -1], [-1, -1], [6, 9], [6, 8], [5, 7], [5, 7], [4, 6], [4, 6], [4, 6], [4, 6], [4, 5], [4, 5], [4, 5], [4, 5], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2]];\nclass CCITTFaxDecoder {\n  constructor(source, options = {}) {\n    if (!source || typeof source.next !== \"function\") {\n      throw new Error('CCITTFaxDecoder - invalid \"source\" parameter.');\n    }\n    this.source = source;\n    this.eof = false;\n    this.encoding = options.K || 0;\n    if (this.encoding === MAX_UINT_32) {\n      this.encoding = -1;\n    }\n    this.eoline = options.EndOfLine || false;\n    this.byteAlign = options.EncodedByteAlign || false;\n    this.columns = options.Columns || 1728;\n    this.rows = options.Rows || 0;\n    this.eoblock = options.EndOfBlock ?? true;\n    this.black = options.BlackIs1 || false;\n    this.codingLine = new Uint32Array(this.columns + 1);\n    this.refLine = new Uint32Array(this.columns + 2);\n    this.codingLine[0] = this.columns;\n    this.codingPos = 0;\n    this.row = 0;\n    this.nextLine2D = this.encoding < 0;\n    this.inputBits = 0;\n    this.inputBuf = 0;\n    this.outputBits = 0;\n    this.rowsDone = false;\n    let code1;\n    while ((code1 = this._lookBits(12)) === 0) {\n      this._eatBits(1);\n    }\n    if (code1 === 1) {\n      this._eatBits(12);\n    }\n    if (this.encoding > 0) {\n      this.nextLine2D = !this._lookBits(1);\n      this._eatBits(1);\n    }\n  }\n  readNextChar() {\n    if (this.eof) {\n      return -1;\n    }\n    const refLine = this.refLine;\n    const codingLine = this.codingLine;\n    const columns = this.columns;\n    let refPos, blackPixels, bits, i;\n    if (this.outputBits === 0) {\n      if (this.rowsDone) {\n        this.eof = true;\n      }\n      if (this.eof) {\n        return -1;\n      }\n      this.err = false;\n      let code1, code2, code3;\n      if (this.nextLine2D) {\n        for (i = 0; codingLine[i] < columns; ++i) {\n          refLine[i] = codingLine[i];\n        }\n        refLine[i++] = columns;\n        refLine[i] = columns;\n        codingLine[0] = 0;\n        this.codingPos = 0;\n        refPos = 0;\n        blackPixels = 0;\n        while (codingLine[this.codingPos] < columns) {\n          code1 = this._getTwoDimCode();\n          switch (code1) {\n            case twoDimPass:\n              this._addPixels(refLine[refPos + 1], blackPixels);\n              if (refLine[refPos + 1] < columns) {\n                refPos += 2;\n              }\n              break;\n            case twoDimHoriz:\n              code1 = code2 = 0;\n              if (blackPixels) {\n                do {\n                  code1 += code3 = this._getBlackCode();\n                } while (code3 >= 64);\n                do {\n                  code2 += code3 = this._getWhiteCode();\n                } while (code3 >= 64);\n              } else {\n                do {\n                  code1 += code3 = this._getWhiteCode();\n                } while (code3 >= 64);\n                do {\n                  code2 += code3 = this._getBlackCode();\n                } while (code3 >= 64);\n              }\n              this._addPixels(codingLine[this.codingPos] + code1, blackPixels);\n              if (codingLine[this.codingPos] < columns) {\n                this._addPixels(codingLine[this.codingPos] + code2, blackPixels ^ 1);\n              }\n              while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {\n                refPos += 2;\n              }\n              break;\n            case twoDimVertR3:\n              this._addPixels(refLine[refPos] + 3, blackPixels);\n              blackPixels ^= 1;\n              if (codingLine[this.codingPos] < columns) {\n                ++refPos;\n                while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {\n                  refPos += 2;\n                }\n              }\n              break;\n            case twoDimVertR2:\n              this._addPixels(refLine[refPos] + 2, blackPixels);\n              blackPixels ^= 1;\n              if (codingLine[this.codingPos] < columns) {\n                ++refPos;\n                while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {\n                  refPos += 2;\n                }\n              }\n              break;\n            case twoDimVertR1:\n              this._addPixels(refLine[refPos] + 1, blackPixels);\n              blackPixels ^= 1;\n              if (codingLine[this.codingPos] < columns) {\n                ++refPos;\n                while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {\n                  refPos += 2;\n                }\n              }\n              break;\n            case twoDimVert0:\n              this._addPixels(refLine[refPos], blackPixels);\n              blackPixels ^= 1;\n              if (codingLine[this.codingPos] < columns) {\n                ++refPos;\n                while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {\n                  refPos += 2;\n                }\n              }\n              break;\n            case twoDimVertL3:\n              this._addPixelsNeg(refLine[refPos] - 3, blackPixels);\n              blackPixels ^= 1;\n              if (codingLine[this.codingPos] < columns) {\n                if (refPos > 0) {\n                  --refPos;\n                } else {\n                  ++refPos;\n                }\n                while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {\n                  refPos += 2;\n                }\n              }\n              break;\n            case twoDimVertL2:\n              this._addPixelsNeg(refLine[refPos] - 2, blackPixels);\n              blackPixels ^= 1;\n              if (codingLine[this.codingPos] < columns) {\n                if (refPos > 0) {\n                  --refPos;\n                } else {\n                  ++refPos;\n                }\n                while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {\n                  refPos += 2;\n                }\n              }\n              break;\n            case twoDimVertL1:\n              this._addPixelsNeg(refLine[refPos] - 1, blackPixels);\n              blackPixels ^= 1;\n              if (codingLine[this.codingPos] < columns) {\n                if (refPos > 0) {\n                  --refPos;\n                } else {\n                  ++refPos;\n                }\n                while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {\n                  refPos += 2;\n                }\n              }\n              break;\n            case ccittEOF:\n              this._addPixels(columns, 0);\n              this.eof = true;\n              break;\n            default:\n              info(\"bad 2d code\");\n              this._addPixels(columns, 0);\n              this.err = true;\n          }\n        }\n      } else {\n        codingLine[0] = 0;\n        this.codingPos = 0;\n        blackPixels = 0;\n        while (codingLine[this.codingPos] < columns) {\n          code1 = 0;\n          if (blackPixels) {\n            do {\n              code1 += code3 = this._getBlackCode();\n            } while (code3 >= 64);\n          } else {\n            do {\n              code1 += code3 = this._getWhiteCode();\n            } while (code3 >= 64);\n          }\n          this._addPixels(codingLine[this.codingPos] + code1, blackPixels);\n          blackPixels ^= 1;\n        }\n      }\n      let gotEOL = false;\n      if (this.byteAlign) {\n        this.inputBits &= ~7;\n      }\n      if (!this.eoblock && this.row === this.rows - 1) {\n        this.rowsDone = true;\n      } else {\n        code1 = this._lookBits(12);\n        if (this.eoline) {\n          while (code1 !== ccittEOF && code1 !== 1) {\n            this._eatBits(1);\n            code1 = this._lookBits(12);\n          }\n        } else {\n          while (code1 === 0) {\n            this._eatBits(1);\n            code1 = this._lookBits(12);\n          }\n        }\n        if (code1 === 1) {\n          this._eatBits(12);\n          gotEOL = true;\n        } else if (code1 === ccittEOF) {\n          this.eof = true;\n        }\n      }\n      if (!this.eof && this.encoding > 0 && !this.rowsDone) {\n        this.nextLine2D = !this._lookBits(1);\n        this._eatBits(1);\n      }\n      if (this.eoblock && gotEOL && this.byteAlign) {\n        code1 = this._lookBits(12);\n        if (code1 === 1) {\n          this._eatBits(12);\n          if (this.encoding > 0) {\n            this._lookBits(1);\n            this._eatBits(1);\n          }\n          if (this.encoding >= 0) {\n            for (i = 0; i < 4; ++i) {\n              code1 = this._lookBits(12);\n              if (code1 !== 1) {\n                info(\"bad rtc code: \" + code1);\n              }\n              this._eatBits(12);\n              if (this.encoding > 0) {\n                this._lookBits(1);\n                this._eatBits(1);\n              }\n            }\n          }\n          this.eof = true;\n        }\n      } else if (this.err && this.eoline) {\n        while (true) {\n          code1 = this._lookBits(13);\n          if (code1 === ccittEOF) {\n            this.eof = true;\n            return -1;\n          }\n          if (code1 >> 1 === 1) {\n            break;\n          }\n          this._eatBits(1);\n        }\n        this._eatBits(12);\n        if (this.encoding > 0) {\n          this._eatBits(1);\n          this.nextLine2D = !(code1 & 1);\n        }\n      }\n      this.outputBits = codingLine[0] > 0 ? codingLine[this.codingPos = 0] : codingLine[this.codingPos = 1];\n      this.row++;\n    }\n    let c;\n    if (this.outputBits >= 8) {\n      c = this.codingPos & 1 ? 0 : 0xff;\n      this.outputBits -= 8;\n      if (this.outputBits === 0 && codingLine[this.codingPos] < columns) {\n        this.codingPos++;\n        this.outputBits = codingLine[this.codingPos] - codingLine[this.codingPos - 1];\n      }\n    } else {\n      bits = 8;\n      c = 0;\n      do {\n        if (typeof this.outputBits !== \"number\") {\n          throw new FormatError('Invalid /CCITTFaxDecode data, \"outputBits\" must be a number.');\n        }\n        if (this.outputBits > bits) {\n          c <<= bits;\n          if (!(this.codingPos & 1)) {\n            c |= 0xff >> 8 - bits;\n          }\n          this.outputBits -= bits;\n          bits = 0;\n        } else {\n          c <<= this.outputBits;\n          if (!(this.codingPos & 1)) {\n            c |= 0xff >> 8 - this.outputBits;\n          }\n          bits -= this.outputBits;\n          this.outputBits = 0;\n          if (codingLine[this.codingPos] < columns) {\n            this.codingPos++;\n            this.outputBits = codingLine[this.codingPos] - codingLine[this.codingPos - 1];\n          } else if (bits > 0) {\n            c <<= bits;\n            bits = 0;\n          }\n        }\n      } while (bits);\n    }\n    if (this.black) {\n      c ^= 0xff;\n    }\n    return c;\n  }\n  _addPixels(a1, blackPixels) {\n    const codingLine = this.codingLine;\n    let codingPos = this.codingPos;\n    if (a1 > codingLine[codingPos]) {\n      if (a1 > this.columns) {\n        info(\"row is wrong length\");\n        this.err = true;\n        a1 = this.columns;\n      }\n      if (codingPos & 1 ^ blackPixels) {\n        ++codingPos;\n      }\n      codingLine[codingPos] = a1;\n    }\n    this.codingPos = codingPos;\n  }\n  _addPixelsNeg(a1, blackPixels) {\n    const codingLine = this.codingLine;\n    let codingPos = this.codingPos;\n    if (a1 > codingLine[codingPos]) {\n      if (a1 > this.columns) {\n        info(\"row is wrong length\");\n        this.err = true;\n        a1 = this.columns;\n      }\n      if (codingPos & 1 ^ blackPixels) {\n        ++codingPos;\n      }\n      codingLine[codingPos] = a1;\n    } else if (a1 < codingLine[codingPos]) {\n      if (a1 < 0) {\n        info(\"invalid code\");\n        this.err = true;\n        a1 = 0;\n      }\n      while (codingPos > 0 && a1 < codingLine[codingPos - 1]) {\n        --codingPos;\n      }\n      codingLine[codingPos] = a1;\n    }\n    this.codingPos = codingPos;\n  }\n  _findTableCode(start, end, table, limit) {\n    const limitValue = limit || 0;\n    for (let i = start; i <= end; ++i) {\n      let code = this._lookBits(i);\n      if (code === ccittEOF) {\n        return [true, 1, false];\n      }\n      if (i < end) {\n        code <<= end - i;\n      }\n      if (!limitValue || code >= limitValue) {\n        const p = table[code - limitValue];\n        if (p[0] === i) {\n          this._eatBits(i);\n          return [true, p[1], true];\n        }\n      }\n    }\n    return [false, 0, false];\n  }\n  _getTwoDimCode() {\n    let code = 0;\n    let p;\n    if (this.eoblock) {\n      code = this._lookBits(7);\n      p = twoDimTable[code];\n      if (p?.[0] > 0) {\n        this._eatBits(p[0]);\n        return p[1];\n      }\n    } else {\n      const result = this._findTableCode(1, 7, twoDimTable);\n      if (result[0] && result[2]) {\n        return result[1];\n      }\n    }\n    info(\"Bad two dim code\");\n    return ccittEOF;\n  }\n  _getWhiteCode() {\n    let code = 0;\n    let p;\n    if (this.eoblock) {\n      code = this._lookBits(12);\n      if (code === ccittEOF) {\n        return 1;\n      }\n      p = code >> 5 === 0 ? whiteTable1[code] : whiteTable2[code >> 3];\n      if (p[0] > 0) {\n        this._eatBits(p[0]);\n        return p[1];\n      }\n    } else {\n      let result = this._findTableCode(1, 9, whiteTable2);\n      if (result[0]) {\n        return result[1];\n      }\n      result = this._findTableCode(11, 12, whiteTable1);\n      if (result[0]) {\n        return result[1];\n      }\n    }\n    info(\"bad white code\");\n    this._eatBits(1);\n    return 1;\n  }\n  _getBlackCode() {\n    let code, p;\n    if (this.eoblock) {\n      code = this._lookBits(13);\n      if (code === ccittEOF) {\n        return 1;\n      }\n      if (code >> 7 === 0) {\n        p = blackTable1[code];\n      } else if (code >> 9 === 0 && code >> 7 !== 0) {\n        p = blackTable2[(code >> 1) - 64];\n      } else {\n        p = blackTable3[code >> 7];\n      }\n      if (p[0] > 0) {\n        this._eatBits(p[0]);\n        return p[1];\n      }\n    } else {\n      let result = this._findTableCode(2, 6, blackTable3);\n      if (result[0]) {\n        return result[1];\n      }\n      result = this._findTableCode(7, 12, blackTable2, 64);\n      if (result[0]) {\n        return result[1];\n      }\n      result = this._findTableCode(10, 13, blackTable1);\n      if (result[0]) {\n        return result[1];\n      }\n    }\n    info(\"bad black code\");\n    this._eatBits(1);\n    return 1;\n  }\n  _lookBits(n) {\n    let c;\n    while (this.inputBits < n) {\n      if ((c = this.source.next()) === -1) {\n        if (this.inputBits === 0) {\n          return ccittEOF;\n        }\n        return this.inputBuf << n - this.inputBits & 0xffff >> 16 - n;\n      }\n      this.inputBuf = this.inputBuf << 8 | c;\n      this.inputBits += 8;\n    }\n    return this.inputBuf >> this.inputBits - n & 0xffff >> 16 - n;\n  }\n  _eatBits(n) {\n    if ((this.inputBits -= n) < 0) {\n      this.inputBits = 0;\n    }\n  }\n}\n\n;// ./src/core/ccitt_stream.js\n\n\n\nclass CCITTFaxStream extends DecodeStream {\n  constructor(str, maybeLength, params) {\n    super(maybeLength);\n    this.str = str;\n    this.dict = str.dict;\n    if (!(params instanceof Dict)) {\n      params = Dict.empty;\n    }\n    const source = {\n      next() {\n        return str.getByte();\n      }\n    };\n    if (params.has(\"Blackls1\")) {\n      params.set(\"BlackIs1\", params.get(\"Blackls1\"));\n    }\n    this.ccittFaxDecoder = new CCITTFaxDecoder(source, {\n      K: params.get(\"K\"),\n      EndOfLine: params.get(\"EndOfLine\"),\n      EncodedByteAlign: params.get(\"EncodedByteAlign\"),\n      Columns: params.get(\"Columns\"),\n      Rows: params.get(\"Rows\"),\n      EndOfBlock: params.get(\"EndOfBlock\"),\n      BlackIs1: params.get(\"BlackIs1\")\n    });\n  }\n  readBlock() {\n    while (!this.eof) {\n      const c = this.ccittFaxDecoder.readNextChar();\n      if (c === -1) {\n        this.eof = true;\n        return;\n      }\n      this.ensureBuffer(this.bufferLength + 1);\n      this.buffer[this.bufferLength++] = c;\n    }\n  }\n}\n\n;// ./src/core/flate_stream.js\n\n\nconst codeLenCodeMap = new Int32Array([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);\nconst lengthDecode = new Int32Array([0x00003, 0x00004, 0x00005, 0x00006, 0x00007, 0x00008, 0x00009, 0x0000a, 0x1000b, 0x1000d, 0x1000f, 0x10011, 0x20013, 0x20017, 0x2001b, 0x2001f, 0x30023, 0x3002b, 0x30033, 0x3003b, 0x40043, 0x40053, 0x40063, 0x40073, 0x50083, 0x500a3, 0x500c3, 0x500e3, 0x00102, 0x00102, 0x00102]);\nconst distDecode = new Int32Array([0x00001, 0x00002, 0x00003, 0x00004, 0x10005, 0x10007, 0x20009, 0x2000d, 0x30011, 0x30019, 0x40021, 0x40031, 0x50041, 0x50061, 0x60081, 0x600c1, 0x70101, 0x70181, 0x80201, 0x80301, 0x90401, 0x90601, 0xa0801, 0xa0c01, 0xb1001, 0xb1801, 0xc2001, 0xc3001, 0xd4001, 0xd6001]);\nconst fixedLitCodeTab = [new Int32Array([0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c0, 0x70108, 0x80060, 0x80020, 0x900a0, 0x80000, 0x80080, 0x80040, 0x900e0, 0x70104, 0x80058, 0x80018, 0x90090, 0x70114, 0x80078, 0x80038, 0x900d0, 0x7010c, 0x80068, 0x80028, 0x900b0, 0x80008, 0x80088, 0x80048, 0x900f0, 0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c8, 0x7010a, 0x80064, 0x80024, 0x900a8, 0x80004, 0x80084, 0x80044, 0x900e8, 0x70106, 0x8005c, 0x8001c, 0x90098, 0x70116, 0x8007c, 0x8003c, 0x900d8, 0x7010e, 0x8006c, 0x8002c, 0x900b8, 0x8000c, 0x8008c, 0x8004c, 0x900f8, 0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c4, 0x70109, 0x80062, 0x80022, 0x900a4, 0x80002, 0x80082, 0x80042, 0x900e4, 0x70105, 0x8005a, 0x8001a, 0x90094, 0x70115, 0x8007a, 0x8003a, 0x900d4, 0x7010d, 0x8006a, 0x8002a, 0x900b4, 0x8000a, 0x8008a, 0x8004a, 0x900f4, 0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cc, 0x7010b, 0x80066, 0x80026, 0x900ac, 0x80006, 0x80086, 0x80046, 0x900ec, 0x70107, 0x8005e, 0x8001e, 0x9009c, 0x70117, 0x8007e, 0x8003e, 0x900dc, 0x7010f, 0x8006e, 0x8002e, 0x900bc, 0x8000e, 0x8008e, 0x8004e, 0x900fc, 0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c2, 0x70108, 0x80061, 0x80021, 0x900a2, 0x80001, 0x80081, 0x80041, 0x900e2, 0x70104, 0x80059, 0x80019, 0x90092, 0x70114, 0x80079, 0x80039, 0x900d2, 0x7010c, 0x80069, 0x80029, 0x900b2, 0x80009, 0x80089, 0x80049, 0x900f2, 0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900ca, 0x7010a, 0x80065, 0x80025, 0x900aa, 0x80005, 0x80085, 0x80045, 0x900ea, 0x70106, 0x8005d, 0x8001d, 0x9009a, 0x70116, 0x8007d, 0x8003d, 0x900da, 0x7010e, 0x8006d, 0x8002d, 0x900ba, 0x8000d, 0x8008d, 0x8004d, 0x900fa, 0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c6, 0x70109, 0x80063, 0x80023, 0x900a6, 0x80003, 0x80083, 0x80043, 0x900e6, 0x70105, 0x8005b, 0x8001b, 0x90096, 0x70115, 0x8007b, 0x8003b, 0x900d6, 0x7010d, 0x8006b, 0x8002b, 0x900b6, 0x8000b, 0x8008b, 0x8004b, 0x900f6, 0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900ce, 0x7010b, 0x80067, 0x80027, 0x900ae, 0x80007, 0x80087, 0x80047, 0x900ee, 0x70107, 0x8005f, 0x8001f, 0x9009e, 0x70117, 0x8007f, 0x8003f, 0x900de, 0x7010f, 0x8006f, 0x8002f, 0x900be, 0x8000f, 0x8008f, 0x8004f, 0x900fe, 0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c1, 0x70108, 0x80060, 0x80020, 0x900a1, 0x80000, 0x80080, 0x80040, 0x900e1, 0x70104, 0x80058, 0x80018, 0x90091, 0x70114, 0x80078, 0x80038, 0x900d1, 0x7010c, 0x80068, 0x80028, 0x900b1, 0x80008, 0x80088, 0x80048, 0x900f1, 0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c9, 0x7010a, 0x80064, 0x80024, 0x900a9, 0x80004, 0x80084, 0x80044, 0x900e9, 0x70106, 0x8005c, 0x8001c, 0x90099, 0x70116, 0x8007c, 0x8003c, 0x900d9, 0x7010e, 0x8006c, 0x8002c, 0x900b9, 0x8000c, 0x8008c, 0x8004c, 0x900f9, 0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c5, 0x70109, 0x80062, 0x80022, 0x900a5, 0x80002, 0x80082, 0x80042, 0x900e5, 0x70105, 0x8005a, 0x8001a, 0x90095, 0x70115, 0x8007a, 0x8003a, 0x900d5, 0x7010d, 0x8006a, 0x8002a, 0x900b5, 0x8000a, 0x8008a, 0x8004a, 0x900f5, 0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cd, 0x7010b, 0x80066, 0x80026, 0x900ad, 0x80006, 0x80086, 0x80046, 0x900ed, 0x70107, 0x8005e, 0x8001e, 0x9009d, 0x70117, 0x8007e, 0x8003e, 0x900dd, 0x7010f, 0x8006e, 0x8002e, 0x900bd, 0x8000e, 0x8008e, 0x8004e, 0x900fd, 0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c3, 0x70108, 0x80061, 0x80021, 0x900a3, 0x80001, 0x80081, 0x80041, 0x900e3, 0x70104, 0x80059, 0x80019, 0x90093, 0x70114, 0x80079, 0x80039, 0x900d3, 0x7010c, 0x80069, 0x80029, 0x900b3, 0x80009, 0x80089, 0x80049, 0x900f3, 0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900cb, 0x7010a, 0x80065, 0x80025, 0x900ab, 0x80005, 0x80085, 0x80045, 0x900eb, 0x70106, 0x8005d, 0x8001d, 0x9009b, 0x70116, 0x8007d, 0x8003d, 0x900db, 0x7010e, 0x8006d, 0x8002d, 0x900bb, 0x8000d, 0x8008d, 0x8004d, 0x900fb, 0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c7, 0x70109, 0x80063, 0x80023, 0x900a7, 0x80003, 0x80083, 0x80043, 0x900e7, 0x70105, 0x8005b, 0x8001b, 0x90097, 0x70115, 0x8007b, 0x8003b, 0x900d7, 0x7010d, 0x8006b, 0x8002b, 0x900b7, 0x8000b, 0x8008b, 0x8004b, 0x900f7, 0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900cf, 0x7010b, 0x80067, 0x80027, 0x900af, 0x80007, 0x80087, 0x80047, 0x900ef, 0x70107, 0x8005f, 0x8001f, 0x9009f, 0x70117, 0x8007f, 0x8003f, 0x900df, 0x7010f, 0x8006f, 0x8002f, 0x900bf, 0x8000f, 0x8008f, 0x8004f, 0x900ff]), 9];\nconst fixedDistCodeTab = [new Int32Array([0x50000, 0x50010, 0x50008, 0x50018, 0x50004, 0x50014, 0x5000c, 0x5001c, 0x50002, 0x50012, 0x5000a, 0x5001a, 0x50006, 0x50016, 0x5000e, 0x00000, 0x50001, 0x50011, 0x50009, 0x50019, 0x50005, 0x50015, 0x5000d, 0x5001d, 0x50003, 0x50013, 0x5000b, 0x5001b, 0x50007, 0x50017, 0x5000f, 0x00000]), 5];\nclass FlateStream extends DecodeStream {\n  constructor(str, maybeLength) {\n    super(maybeLength);\n    this.str = str;\n    this.dict = str.dict;\n    const cmf = str.getByte();\n    const flg = str.getByte();\n    if (cmf === -1 || flg === -1) {\n      throw new FormatError(`Invalid header in flate stream: ${cmf}, ${flg}`);\n    }\n    if ((cmf & 0x0f) !== 0x08) {\n      throw new FormatError(`Unknown compression method in flate stream: ${cmf}, ${flg}`);\n    }\n    if (((cmf << 8) + flg) % 31 !== 0) {\n      throw new FormatError(`Bad FCHECK in flate stream: ${cmf}, ${flg}`);\n    }\n    if (flg & 0x20) {\n      throw new FormatError(`FDICT bit set in flate stream: ${cmf}, ${flg}`);\n    }\n    this.codeSize = 0;\n    this.codeBuf = 0;\n  }\n  getBits(bits) {\n    const str = this.str;\n    let codeSize = this.codeSize;\n    let codeBuf = this.codeBuf;\n    let b;\n    while (codeSize < bits) {\n      if ((b = str.getByte()) === -1) {\n        throw new FormatError(\"Bad encoding in flate stream\");\n      }\n      codeBuf |= b << codeSize;\n      codeSize += 8;\n    }\n    b = codeBuf & (1 << bits) - 1;\n    this.codeBuf = codeBuf >> bits;\n    this.codeSize = codeSize -= bits;\n    return b;\n  }\n  getCode(table) {\n    const str = this.str;\n    const codes = table[0];\n    const maxLen = table[1];\n    let codeSize = this.codeSize;\n    let codeBuf = this.codeBuf;\n    let b;\n    while (codeSize < maxLen) {\n      if ((b = str.getByte()) === -1) {\n        break;\n      }\n      codeBuf |= b << codeSize;\n      codeSize += 8;\n    }\n    const code = codes[codeBuf & (1 << maxLen) - 1];\n    const codeLen = code >> 16;\n    const codeVal = code & 0xffff;\n    if (codeLen < 1 || codeSize < codeLen) {\n      throw new FormatError(\"Bad encoding in flate stream\");\n    }\n    this.codeBuf = codeBuf >> codeLen;\n    this.codeSize = codeSize - codeLen;\n    return codeVal;\n  }\n  generateHuffmanTable(lengths) {\n    const n = lengths.length;\n    let maxLen = 0;\n    let i;\n    for (i = 0; i < n; ++i) {\n      if (lengths[i] > maxLen) {\n        maxLen = lengths[i];\n      }\n    }\n    const size = 1 << maxLen;\n    const codes = new Int32Array(size);\n    for (let len = 1, code = 0, skip = 2; len <= maxLen; ++len, code <<= 1, skip <<= 1) {\n      for (let val = 0; val < n; ++val) {\n        if (lengths[val] === len) {\n          let code2 = 0;\n          let t = code;\n          for (i = 0; i < len; ++i) {\n            code2 = code2 << 1 | t & 1;\n            t >>= 1;\n          }\n          for (i = code2; i < size; i += skip) {\n            codes[i] = len << 16 | val;\n          }\n          ++code;\n        }\n      }\n    }\n    return [codes, maxLen];\n  }\n  #endsStreamOnError(err) {\n    info(err);\n    this.eof = true;\n  }\n  readBlock() {\n    let buffer, len;\n    const str = this.str;\n    let hdr = this.getBits(3);\n    if (hdr & 1) {\n      this.eof = true;\n    }\n    hdr >>= 1;\n    if (hdr === 0) {\n      let b;\n      if ((b = str.getByte()) === -1) {\n        this.#endsStreamOnError(\"Bad block header in flate stream\");\n        return;\n      }\n      let blockLen = b;\n      if ((b = str.getByte()) === -1) {\n        this.#endsStreamOnError(\"Bad block header in flate stream\");\n        return;\n      }\n      blockLen |= b << 8;\n      if ((b = str.getByte()) === -1) {\n        this.#endsStreamOnError(\"Bad block header in flate stream\");\n        return;\n      }\n      let check = b;\n      if ((b = str.getByte()) === -1) {\n        this.#endsStreamOnError(\"Bad block header in flate stream\");\n        return;\n      }\n      check |= b << 8;\n      if (check !== (~blockLen & 0xffff) && (blockLen !== 0 || check !== 0)) {\n        throw new FormatError(\"Bad uncompressed block length in flate stream\");\n      }\n      this.codeBuf = 0;\n      this.codeSize = 0;\n      const bufferLength = this.bufferLength,\n        end = bufferLength + blockLen;\n      buffer = this.ensureBuffer(end);\n      this.bufferLength = end;\n      if (blockLen === 0) {\n        if (str.peekByte() === -1) {\n          this.eof = true;\n        }\n      } else {\n        const block = str.getBytes(blockLen);\n        buffer.set(block, bufferLength);\n        if (block.length < blockLen) {\n          this.eof = true;\n        }\n      }\n      return;\n    }\n    let litCodeTable;\n    let distCodeTable;\n    if (hdr === 1) {\n      litCodeTable = fixedLitCodeTab;\n      distCodeTable = fixedDistCodeTab;\n    } else if (hdr === 2) {\n      const numLitCodes = this.getBits(5) + 257;\n      const numDistCodes = this.getBits(5) + 1;\n      const numCodeLenCodes = this.getBits(4) + 4;\n      const codeLenCodeLengths = new Uint8Array(codeLenCodeMap.length);\n      let i;\n      for (i = 0; i < numCodeLenCodes; ++i) {\n        codeLenCodeLengths[codeLenCodeMap[i]] = this.getBits(3);\n      }\n      const codeLenCodeTab = this.generateHuffmanTable(codeLenCodeLengths);\n      len = 0;\n      i = 0;\n      const codes = numLitCodes + numDistCodes;\n      const codeLengths = new Uint8Array(codes);\n      let bitsLength, bitsOffset, what;\n      while (i < codes) {\n        const code = this.getCode(codeLenCodeTab);\n        if (code === 16) {\n          bitsLength = 2;\n          bitsOffset = 3;\n          what = len;\n        } else if (code === 17) {\n          bitsLength = 3;\n          bitsOffset = 3;\n          what = len = 0;\n        } else if (code === 18) {\n          bitsLength = 7;\n          bitsOffset = 11;\n          what = len = 0;\n        } else {\n          codeLengths[i++] = len = code;\n          continue;\n        }\n        let repeatLength = this.getBits(bitsLength) + bitsOffset;\n        while (repeatLength-- > 0) {\n          codeLengths[i++] = what;\n        }\n      }\n      litCodeTable = this.generateHuffmanTable(codeLengths.subarray(0, numLitCodes));\n      distCodeTable = this.generateHuffmanTable(codeLengths.subarray(numLitCodes, codes));\n    } else {\n      throw new FormatError(\"Unknown block type in flate stream\");\n    }\n    buffer = this.buffer;\n    let limit = buffer ? buffer.length : 0;\n    let pos = this.bufferLength;\n    while (true) {\n      let code1 = this.getCode(litCodeTable);\n      if (code1 < 256) {\n        if (pos + 1 >= limit) {\n          buffer = this.ensureBuffer(pos + 1);\n          limit = buffer.length;\n        }\n        buffer[pos++] = code1;\n        continue;\n      }\n      if (code1 === 256) {\n        this.bufferLength = pos;\n        return;\n      }\n      code1 -= 257;\n      code1 = lengthDecode[code1];\n      let code2 = code1 >> 16;\n      if (code2 > 0) {\n        code2 = this.getBits(code2);\n      }\n      len = (code1 & 0xffff) + code2;\n      code1 = this.getCode(distCodeTable);\n      code1 = distDecode[code1];\n      code2 = code1 >> 16;\n      if (code2 > 0) {\n        code2 = this.getBits(code2);\n      }\n      const dist = (code1 & 0xffff) + code2;\n      if (pos + len >= limit) {\n        buffer = this.ensureBuffer(pos + len);\n        limit = buffer.length;\n      }\n      for (let k = 0; k < len; ++k, ++pos) {\n        buffer[pos] = buffer[pos - dist];\n      }\n    }\n  }\n}\n\n;// ./src/core/arithmetic_decoder.js\nconst QeTable = [{\n  qe: 0x5601,\n  nmps: 1,\n  nlps: 1,\n  switchFlag: 1\n}, {\n  qe: 0x3401,\n  nmps: 2,\n  nlps: 6,\n  switchFlag: 0\n}, {\n  qe: 0x1801,\n  nmps: 3,\n  nlps: 9,\n  switchFlag: 0\n}, {\n  qe: 0x0ac1,\n  nmps: 4,\n  nlps: 12,\n  switchFlag: 0\n}, {\n  qe: 0x0521,\n  nmps: 5,\n  nlps: 29,\n  switchFlag: 0\n}, {\n  qe: 0x0221,\n  nmps: 38,\n  nlps: 33,\n  switchFlag: 0\n}, {\n  qe: 0x5601,\n  nmps: 7,\n  nlps: 6,\n  switchFlag: 1\n}, {\n  qe: 0x5401,\n  nmps: 8,\n  nlps: 14,\n  switchFlag: 0\n}, {\n  qe: 0x4801,\n  nmps: 9,\n  nlps: 14,\n  switchFlag: 0\n}, {\n  qe: 0x3801,\n  nmps: 10,\n  nlps: 14,\n  switchFlag: 0\n}, {\n  qe: 0x3001,\n  nmps: 11,\n  nlps: 17,\n  switchFlag: 0\n}, {\n  qe: 0x2401,\n  nmps: 12,\n  nlps: 18,\n  switchFlag: 0\n}, {\n  qe: 0x1c01,\n  nmps: 13,\n  nlps: 20,\n  switchFlag: 0\n}, {\n  qe: 0x1601,\n  nmps: 29,\n  nlps: 21,\n  switchFlag: 0\n}, {\n  qe: 0x5601,\n  nmps: 15,\n  nlps: 14,\n  switchFlag: 1\n}, {\n  qe: 0x5401,\n  nmps: 16,\n  nlps: 14,\n  switchFlag: 0\n}, {\n  qe: 0x5101,\n  nmps: 17,\n  nlps: 15,\n  switchFlag: 0\n}, {\n  qe: 0x4801,\n  nmps: 18,\n  nlps: 16,\n  switchFlag: 0\n}, {\n  qe: 0x3801,\n  nmps: 19,\n  nlps: 17,\n  switchFlag: 0\n}, {\n  qe: 0x3401,\n  nmps: 20,\n  nlps: 18,\n  switchFlag: 0\n}, {\n  qe: 0x3001,\n  nmps: 21,\n  nlps: 19,\n  switchFlag: 0\n}, {\n  qe: 0x2801,\n  nmps: 22,\n  nlps: 19,\n  switchFlag: 0\n}, {\n  qe: 0x2401,\n  nmps: 23,\n  nlps: 20,\n  switchFlag: 0\n}, {\n  qe: 0x2201,\n  nmps: 24,\n  nlps: 21,\n  switchFlag: 0\n}, {\n  qe: 0x1c01,\n  nmps: 25,\n  nlps: 22,\n  switchFlag: 0\n}, {\n  qe: 0x1801,\n  nmps: 26,\n  nlps: 23,\n  switchFlag: 0\n}, {\n  qe: 0x1601,\n  nmps: 27,\n  nlps: 24,\n  switchFlag: 0\n}, {\n  qe: 0x1401,\n  nmps: 28,\n  nlps: 25,\n  switchFlag: 0\n}, {\n  qe: 0x1201,\n  nmps: 29,\n  nlps: 26,\n  switchFlag: 0\n}, {\n  qe: 0x1101,\n  nmps: 30,\n  nlps: 27,\n  switchFlag: 0\n}, {\n  qe: 0x0ac1,\n  nmps: 31,\n  nlps: 28,\n  switchFlag: 0\n}, {\n  qe: 0x09c1,\n  nmps: 32,\n  nlps: 29,\n  switchFlag: 0\n}, {\n  qe: 0x08a1,\n  nmps: 33,\n  nlps: 30,\n  switchFlag: 0\n}, {\n  qe: 0x0521,\n  nmps: 34,\n  nlps: 31,\n  switchFlag: 0\n}, {\n  qe: 0x0441,\n  nmps: 35,\n  nlps: 32,\n  switchFlag: 0\n}, {\n  qe: 0x02a1,\n  nmps: 36,\n  nlps: 33,\n  switchFlag: 0\n}, {\n  qe: 0x0221,\n  nmps: 37,\n  nlps: 34,\n  switchFlag: 0\n}, {\n  qe: 0x0141,\n  nmps: 38,\n  nlps: 35,\n  switchFlag: 0\n}, {\n  qe: 0x0111,\n  nmps: 39,\n  nlps: 36,\n  switchFlag: 0\n}, {\n  qe: 0x0085,\n  nmps: 40,\n  nlps: 37,\n  switchFlag: 0\n}, {\n  qe: 0x0049,\n  nmps: 41,\n  nlps: 38,\n  switchFlag: 0\n}, {\n  qe: 0x0025,\n  nmps: 42,\n  nlps: 39,\n  switchFlag: 0\n}, {\n  qe: 0x0015,\n  nmps: 43,\n  nlps: 40,\n  switchFlag: 0\n}, {\n  qe: 0x0009,\n  nmps: 44,\n  nlps: 41,\n  switchFlag: 0\n}, {\n  qe: 0x0005,\n  nmps: 45,\n  nlps: 42,\n  switchFlag: 0\n}, {\n  qe: 0x0001,\n  nmps: 45,\n  nlps: 43,\n  switchFlag: 0\n}, {\n  qe: 0x5601,\n  nmps: 46,\n  nlps: 46,\n  switchFlag: 0\n}];\nclass ArithmeticDecoder {\n  constructor(data, start, end) {\n    this.data = data;\n    this.bp = start;\n    this.dataEnd = end;\n    this.chigh = data[start];\n    this.clow = 0;\n    this.byteIn();\n    this.chigh = this.chigh << 7 & 0xffff | this.clow >> 9 & 0x7f;\n    this.clow = this.clow << 7 & 0xffff;\n    this.ct -= 7;\n    this.a = 0x8000;\n  }\n  byteIn() {\n    const data = this.data;\n    let bp = this.bp;\n    if (data[bp] === 0xff) {\n      if (data[bp + 1] > 0x8f) {\n        this.clow += 0xff00;\n        this.ct = 8;\n      } else {\n        bp++;\n        this.clow += data[bp] << 9;\n        this.ct = 7;\n        this.bp = bp;\n      }\n    } else {\n      bp++;\n      this.clow += bp < this.dataEnd ? data[bp] << 8 : 0xff00;\n      this.ct = 8;\n      this.bp = bp;\n    }\n    if (this.clow > 0xffff) {\n      this.chigh += this.clow >> 16;\n      this.clow &= 0xffff;\n    }\n  }\n  readBit(contexts, pos) {\n    let cx_index = contexts[pos] >> 1,\n      cx_mps = contexts[pos] & 1;\n    const qeTableIcx = QeTable[cx_index];\n    const qeIcx = qeTableIcx.qe;\n    let d;\n    let a = this.a - qeIcx;\n    if (this.chigh < qeIcx) {\n      if (a < qeIcx) {\n        a = qeIcx;\n        d = cx_mps;\n        cx_index = qeTableIcx.nmps;\n      } else {\n        a = qeIcx;\n        d = 1 ^ cx_mps;\n        if (qeTableIcx.switchFlag === 1) {\n          cx_mps = d;\n        }\n        cx_index = qeTableIcx.nlps;\n      }\n    } else {\n      this.chigh -= qeIcx;\n      if ((a & 0x8000) !== 0) {\n        this.a = a;\n        return cx_mps;\n      }\n      if (a < qeIcx) {\n        d = 1 ^ cx_mps;\n        if (qeTableIcx.switchFlag === 1) {\n          cx_mps = d;\n        }\n        cx_index = qeTableIcx.nlps;\n      } else {\n        d = cx_mps;\n        cx_index = qeTableIcx.nmps;\n      }\n    }\n    do {\n      if (this.ct === 0) {\n        this.byteIn();\n      }\n      a <<= 1;\n      this.chigh = this.chigh << 1 & 0xffff | this.clow >> 15 & 1;\n      this.clow = this.clow << 1 & 0xffff;\n      this.ct--;\n    } while ((a & 0x8000) === 0);\n    this.a = a;\n    contexts[pos] = cx_index << 1 | cx_mps;\n    return d;\n  }\n}\n\n;// ./src/core/jbig2.js\n\n\n\n\nclass Jbig2Error extends BaseException {\n  constructor(msg) {\n    super(msg, \"Jbig2Error\");\n  }\n}\nclass ContextCache {\n  getContexts(id) {\n    if (id in this) {\n      return this[id];\n    }\n    return this[id] = new Int8Array(1 << 16);\n  }\n}\nclass DecodingContext {\n  constructor(data, start, end) {\n    this.data = data;\n    this.start = start;\n    this.end = end;\n  }\n  get decoder() {\n    const decoder = new ArithmeticDecoder(this.data, this.start, this.end);\n    return shadow(this, \"decoder\", decoder);\n  }\n  get contextCache() {\n    const cache = new ContextCache();\n    return shadow(this, \"contextCache\", cache);\n  }\n}\nconst MAX_INT_32 = 2 ** 31 - 1;\nconst MIN_INT_32 = -(2 ** 31);\nfunction decodeInteger(contextCache, procedure, decoder) {\n  const contexts = contextCache.getContexts(procedure);\n  let prev = 1;\n  function readBits(length) {\n    let v = 0;\n    for (let i = 0; i < length; i++) {\n      const bit = decoder.readBit(contexts, prev);\n      prev = prev < 256 ? prev << 1 | bit : (prev << 1 | bit) & 511 | 256;\n      v = v << 1 | bit;\n    }\n    return v >>> 0;\n  }\n  const sign = readBits(1);\n  const value = readBits(1) ? readBits(1) ? readBits(1) ? readBits(1) ? readBits(1) ? readBits(32) + 4436 : readBits(12) + 340 : readBits(8) + 84 : readBits(6) + 20 : readBits(4) + 4 : readBits(2);\n  let signedValue;\n  if (sign === 0) {\n    signedValue = value;\n  } else if (value > 0) {\n    signedValue = -value;\n  }\n  if (signedValue >= MIN_INT_32 && signedValue <= MAX_INT_32) {\n    return signedValue;\n  }\n  return null;\n}\nfunction decodeIAID(contextCache, decoder, codeLength) {\n  const contexts = contextCache.getContexts(\"IAID\");\n  let prev = 1;\n  for (let i = 0; i < codeLength; i++) {\n    const bit = decoder.readBit(contexts, prev);\n    prev = prev << 1 | bit;\n  }\n  if (codeLength < 31) {\n    return prev & (1 << codeLength) - 1;\n  }\n  return prev & 0x7fffffff;\n}\nconst SegmentTypes = [\"SymbolDictionary\", null, null, null, \"IntermediateTextRegion\", null, \"ImmediateTextRegion\", \"ImmediateLosslessTextRegion\", null, null, null, null, null, null, null, null, \"PatternDictionary\", null, null, null, \"IntermediateHalftoneRegion\", null, \"ImmediateHalftoneRegion\", \"ImmediateLosslessHalftoneRegion\", null, null, null, null, null, null, null, null, null, null, null, null, \"IntermediateGenericRegion\", null, \"ImmediateGenericRegion\", \"ImmediateLosslessGenericRegion\", \"IntermediateGenericRefinementRegion\", null, \"ImmediateGenericRefinementRegion\", \"ImmediateLosslessGenericRefinementRegion\", null, null, null, null, \"PageInformation\", \"EndOfPage\", \"EndOfStripe\", \"EndOfFile\", \"Profiles\", \"Tables\", null, null, null, null, null, null, null, null, \"Extension\"];\nconst CodingTemplates = [[{\n  x: -1,\n  y: -2\n}, {\n  x: 0,\n  y: -2\n}, {\n  x: 1,\n  y: -2\n}, {\n  x: -2,\n  y: -1\n}, {\n  x: -1,\n  y: -1\n}, {\n  x: 0,\n  y: -1\n}, {\n  x: 1,\n  y: -1\n}, {\n  x: 2,\n  y: -1\n}, {\n  x: -4,\n  y: 0\n}, {\n  x: -3,\n  y: 0\n}, {\n  x: -2,\n  y: 0\n}, {\n  x: -1,\n  y: 0\n}], [{\n  x: -1,\n  y: -2\n}, {\n  x: 0,\n  y: -2\n}, {\n  x: 1,\n  y: -2\n}, {\n  x: 2,\n  y: -2\n}, {\n  x: -2,\n  y: -1\n}, {\n  x: -1,\n  y: -1\n}, {\n  x: 0,\n  y: -1\n}, {\n  x: 1,\n  y: -1\n}, {\n  x: 2,\n  y: -1\n}, {\n  x: -3,\n  y: 0\n}, {\n  x: -2,\n  y: 0\n}, {\n  x: -1,\n  y: 0\n}], [{\n  x: -1,\n  y: -2\n}, {\n  x: 0,\n  y: -2\n}, {\n  x: 1,\n  y: -2\n}, {\n  x: -2,\n  y: -1\n}, {\n  x: -1,\n  y: -1\n}, {\n  x: 0,\n  y: -1\n}, {\n  x: 1,\n  y: -1\n}, {\n  x: -2,\n  y: 0\n}, {\n  x: -1,\n  y: 0\n}], [{\n  x: -3,\n  y: -1\n}, {\n  x: -2,\n  y: -1\n}, {\n  x: -1,\n  y: -1\n}, {\n  x: 0,\n  y: -1\n}, {\n  x: 1,\n  y: -1\n}, {\n  x: -4,\n  y: 0\n}, {\n  x: -3,\n  y: 0\n}, {\n  x: -2,\n  y: 0\n}, {\n  x: -1,\n  y: 0\n}]];\nconst RefinementTemplates = [{\n  coding: [{\n    x: 0,\n    y: -1\n  }, {\n    x: 1,\n    y: -1\n  }, {\n    x: -1,\n    y: 0\n  }],\n  reference: [{\n    x: 0,\n    y: -1\n  }, {\n    x: 1,\n    y: -1\n  }, {\n    x: -1,\n    y: 0\n  }, {\n    x: 0,\n    y: 0\n  }, {\n    x: 1,\n    y: 0\n  }, {\n    x: -1,\n    y: 1\n  }, {\n    x: 0,\n    y: 1\n  }, {\n    x: 1,\n    y: 1\n  }]\n}, {\n  coding: [{\n    x: -1,\n    y: -1\n  }, {\n    x: 0,\n    y: -1\n  }, {\n    x: 1,\n    y: -1\n  }, {\n    x: -1,\n    y: 0\n  }],\n  reference: [{\n    x: 0,\n    y: -1\n  }, {\n    x: -1,\n    y: 0\n  }, {\n    x: 0,\n    y: 0\n  }, {\n    x: 1,\n    y: 0\n  }, {\n    x: 0,\n    y: 1\n  }, {\n    x: 1,\n    y: 1\n  }]\n}];\nconst ReusedContexts = [0x9b25, 0x0795, 0x00e5, 0x0195];\nconst RefinementReusedContexts = [0x0020, 0x0008];\nfunction decodeBitmapTemplate0(width, height, decodingContext) {\n  const decoder = decodingContext.decoder;\n  const contexts = decodingContext.contextCache.getContexts(\"GB\");\n  const bitmap = [];\n  let contextLabel, i, j, pixel, row, row1, row2;\n  const OLD_PIXEL_MASK = 0x7bf7;\n  for (i = 0; i < height; i++) {\n    row = bitmap[i] = new Uint8Array(width);\n    row1 = i < 1 ? row : bitmap[i - 1];\n    row2 = i < 2 ? row : bitmap[i - 2];\n    contextLabel = row2[0] << 13 | row2[1] << 12 | row2[2] << 11 | row1[0] << 7 | row1[1] << 6 | row1[2] << 5 | row1[3] << 4;\n    for (j = 0; j < width; j++) {\n      row[j] = pixel = decoder.readBit(contexts, contextLabel);\n      contextLabel = (contextLabel & OLD_PIXEL_MASK) << 1 | (j + 3 < width ? row2[j + 3] << 11 : 0) | (j + 4 < width ? row1[j + 4] << 4 : 0) | pixel;\n    }\n  }\n  return bitmap;\n}\nfunction decodeBitmap(mmr, width, height, templateIndex, prediction, skip, at, decodingContext) {\n  if (mmr) {\n    const input = new Reader(decodingContext.data, decodingContext.start, decodingContext.end);\n    return decodeMMRBitmap(input, width, height, false);\n  }\n  if (templateIndex === 0 && !skip && !prediction && at.length === 4 && at[0].x === 3 && at[0].y === -1 && at[1].x === -3 && at[1].y === -1 && at[2].x === 2 && at[2].y === -2 && at[3].x === -2 && at[3].y === -2) {\n    return decodeBitmapTemplate0(width, height, decodingContext);\n  }\n  const useskip = !!skip;\n  const template = CodingTemplates[templateIndex].concat(at);\n  template.sort(function (a, b) {\n    return a.y - b.y || a.x - b.x;\n  });\n  const templateLength = template.length;\n  const templateX = new Int8Array(templateLength);\n  const templateY = new Int8Array(templateLength);\n  const changingTemplateEntries = [];\n  let reuseMask = 0,\n    minX = 0,\n    maxX = 0,\n    minY = 0;\n  let c, k;\n  for (k = 0; k < templateLength; k++) {\n    templateX[k] = template[k].x;\n    templateY[k] = template[k].y;\n    minX = Math.min(minX, template[k].x);\n    maxX = Math.max(maxX, template[k].x);\n    minY = Math.min(minY, template[k].y);\n    if (k < templateLength - 1 && template[k].y === template[k + 1].y && template[k].x === template[k + 1].x - 1) {\n      reuseMask |= 1 << templateLength - 1 - k;\n    } else {\n      changingTemplateEntries.push(k);\n    }\n  }\n  const changingEntriesLength = changingTemplateEntries.length;\n  const changingTemplateX = new Int8Array(changingEntriesLength);\n  const changingTemplateY = new Int8Array(changingEntriesLength);\n  const changingTemplateBit = new Uint16Array(changingEntriesLength);\n  for (c = 0; c < changingEntriesLength; c++) {\n    k = changingTemplateEntries[c];\n    changingTemplateX[c] = template[k].x;\n    changingTemplateY[c] = template[k].y;\n    changingTemplateBit[c] = 1 << templateLength - 1 - k;\n  }\n  const sbb_left = -minX;\n  const sbb_top = -minY;\n  const sbb_right = width - maxX;\n  const pseudoPixelContext = ReusedContexts[templateIndex];\n  let row = new Uint8Array(width);\n  const bitmap = [];\n  const decoder = decodingContext.decoder;\n  const contexts = decodingContext.contextCache.getContexts(\"GB\");\n  let ltp = 0,\n    j,\n    i0,\n    j0,\n    contextLabel = 0,\n    bit,\n    shift;\n  for (let i = 0; i < height; i++) {\n    if (prediction) {\n      const sltp = decoder.readBit(contexts, pseudoPixelContext);\n      ltp ^= sltp;\n      if (ltp) {\n        bitmap.push(row);\n        continue;\n      }\n    }\n    row = new Uint8Array(row);\n    bitmap.push(row);\n    for (j = 0; j < width; j++) {\n      if (useskip && skip[i][j]) {\n        row[j] = 0;\n        continue;\n      }\n      if (j >= sbb_left && j < sbb_right && i >= sbb_top) {\n        contextLabel = contextLabel << 1 & reuseMask;\n        for (k = 0; k < changingEntriesLength; k++) {\n          i0 = i + changingTemplateY[k];\n          j0 = j + changingTemplateX[k];\n          bit = bitmap[i0][j0];\n          if (bit) {\n            bit = changingTemplateBit[k];\n            contextLabel |= bit;\n          }\n        }\n      } else {\n        contextLabel = 0;\n        shift = templateLength - 1;\n        for (k = 0; k < templateLength; k++, shift--) {\n          j0 = j + templateX[k];\n          if (j0 >= 0 && j0 < width) {\n            i0 = i + templateY[k];\n            if (i0 >= 0) {\n              bit = bitmap[i0][j0];\n              if (bit) {\n                contextLabel |= bit << shift;\n              }\n            }\n          }\n        }\n      }\n      const pixel = decoder.readBit(contexts, contextLabel);\n      row[j] = pixel;\n    }\n  }\n  return bitmap;\n}\nfunction decodeRefinement(width, height, templateIndex, referenceBitmap, offsetX, offsetY, prediction, at, decodingContext) {\n  let codingTemplate = RefinementTemplates[templateIndex].coding;\n  if (templateIndex === 0) {\n    codingTemplate = codingTemplate.concat([at[0]]);\n  }\n  const codingTemplateLength = codingTemplate.length;\n  const codingTemplateX = new Int32Array(codingTemplateLength);\n  const codingTemplateY = new Int32Array(codingTemplateLength);\n  let k;\n  for (k = 0; k < codingTemplateLength; k++) {\n    codingTemplateX[k] = codingTemplate[k].x;\n    codingTemplateY[k] = codingTemplate[k].y;\n  }\n  let referenceTemplate = RefinementTemplates[templateIndex].reference;\n  if (templateIndex === 0) {\n    referenceTemplate = referenceTemplate.concat([at[1]]);\n  }\n  const referenceTemplateLength = referenceTemplate.length;\n  const referenceTemplateX = new Int32Array(referenceTemplateLength);\n  const referenceTemplateY = new Int32Array(referenceTemplateLength);\n  for (k = 0; k < referenceTemplateLength; k++) {\n    referenceTemplateX[k] = referenceTemplate[k].x;\n    referenceTemplateY[k] = referenceTemplate[k].y;\n  }\n  const referenceWidth = referenceBitmap[0].length;\n  const referenceHeight = referenceBitmap.length;\n  const pseudoPixelContext = RefinementReusedContexts[templateIndex];\n  const bitmap = [];\n  const decoder = decodingContext.decoder;\n  const contexts = decodingContext.contextCache.getContexts(\"GR\");\n  let ltp = 0;\n  for (let i = 0; i < height; i++) {\n    if (prediction) {\n      const sltp = decoder.readBit(contexts, pseudoPixelContext);\n      ltp ^= sltp;\n      if (ltp) {\n        throw new Jbig2Error(\"prediction is not supported\");\n      }\n    }\n    const row = new Uint8Array(width);\n    bitmap.push(row);\n    for (let j = 0; j < width; j++) {\n      let i0, j0;\n      let contextLabel = 0;\n      for (k = 0; k < codingTemplateLength; k++) {\n        i0 = i + codingTemplateY[k];\n        j0 = j + codingTemplateX[k];\n        if (i0 < 0 || j0 < 0 || j0 >= width) {\n          contextLabel <<= 1;\n        } else {\n          contextLabel = contextLabel << 1 | bitmap[i0][j0];\n        }\n      }\n      for (k = 0; k < referenceTemplateLength; k++) {\n        i0 = i + referenceTemplateY[k] - offsetY;\n        j0 = j + referenceTemplateX[k] - offsetX;\n        if (i0 < 0 || i0 >= referenceHeight || j0 < 0 || j0 >= referenceWidth) {\n          contextLabel <<= 1;\n        } else {\n          contextLabel = contextLabel << 1 | referenceBitmap[i0][j0];\n        }\n      }\n      const pixel = decoder.readBit(contexts, contextLabel);\n      row[j] = pixel;\n    }\n  }\n  return bitmap;\n}\nfunction decodeSymbolDictionary(huffman, refinement, symbols, numberOfNewSymbols, numberOfExportedSymbols, huffmanTables, templateIndex, at, refinementTemplateIndex, refinementAt, decodingContext, huffmanInput) {\n  if (huffman && refinement) {\n    throw new Jbig2Error(\"symbol refinement with Huffman is not supported\");\n  }\n  const newSymbols = [];\n  let currentHeight = 0;\n  let symbolCodeLength = log2(symbols.length + numberOfNewSymbols);\n  const decoder = decodingContext.decoder;\n  const contextCache = decodingContext.contextCache;\n  let tableB1, symbolWidths;\n  if (huffman) {\n    tableB1 = getStandardTable(1);\n    symbolWidths = [];\n    symbolCodeLength = Math.max(symbolCodeLength, 1);\n  }\n  while (newSymbols.length < numberOfNewSymbols) {\n    const deltaHeight = huffman ? huffmanTables.tableDeltaHeight.decode(huffmanInput) : decodeInteger(contextCache, \"IADH\", decoder);\n    currentHeight += deltaHeight;\n    let currentWidth = 0,\n      totalWidth = 0;\n    const firstSymbol = huffman ? symbolWidths.length : 0;\n    while (true) {\n      const deltaWidth = huffman ? huffmanTables.tableDeltaWidth.decode(huffmanInput) : decodeInteger(contextCache, \"IADW\", decoder);\n      if (deltaWidth === null) {\n        break;\n      }\n      currentWidth += deltaWidth;\n      totalWidth += currentWidth;\n      let bitmap;\n      if (refinement) {\n        const numberOfInstances = decodeInteger(contextCache, \"IAAI\", decoder);\n        if (numberOfInstances > 1) {\n          bitmap = decodeTextRegion(huffman, refinement, currentWidth, currentHeight, 0, numberOfInstances, 1, symbols.concat(newSymbols), symbolCodeLength, 0, 0, 1, 0, huffmanTables, refinementTemplateIndex, refinementAt, decodingContext, 0, huffmanInput);\n        } else {\n          const symbolId = decodeIAID(contextCache, decoder, symbolCodeLength);\n          const rdx = decodeInteger(contextCache, \"IARDX\", decoder);\n          const rdy = decodeInteger(contextCache, \"IARDY\", decoder);\n          const symbol = symbolId < symbols.length ? symbols[symbolId] : newSymbols[symbolId - symbols.length];\n          bitmap = decodeRefinement(currentWidth, currentHeight, refinementTemplateIndex, symbol, rdx, rdy, false, refinementAt, decodingContext);\n        }\n        newSymbols.push(bitmap);\n      } else if (huffman) {\n        symbolWidths.push(currentWidth);\n      } else {\n        bitmap = decodeBitmap(false, currentWidth, currentHeight, templateIndex, false, null, at, decodingContext);\n        newSymbols.push(bitmap);\n      }\n    }\n    if (huffman && !refinement) {\n      const bitmapSize = huffmanTables.tableBitmapSize.decode(huffmanInput);\n      huffmanInput.byteAlign();\n      let collectiveBitmap;\n      if (bitmapSize === 0) {\n        collectiveBitmap = readUncompressedBitmap(huffmanInput, totalWidth, currentHeight);\n      } else {\n        const originalEnd = huffmanInput.end;\n        const bitmapEnd = huffmanInput.position + bitmapSize;\n        huffmanInput.end = bitmapEnd;\n        collectiveBitmap = decodeMMRBitmap(huffmanInput, totalWidth, currentHeight, false);\n        huffmanInput.end = originalEnd;\n        huffmanInput.position = bitmapEnd;\n      }\n      const numberOfSymbolsDecoded = symbolWidths.length;\n      if (firstSymbol === numberOfSymbolsDecoded - 1) {\n        newSymbols.push(collectiveBitmap);\n      } else {\n        let i,\n          y,\n          xMin = 0,\n          xMax,\n          bitmapWidth,\n          symbolBitmap;\n        for (i = firstSymbol; i < numberOfSymbolsDecoded; i++) {\n          bitmapWidth = symbolWidths[i];\n          xMax = xMin + bitmapWidth;\n          symbolBitmap = [];\n          for (y = 0; y < currentHeight; y++) {\n            symbolBitmap.push(collectiveBitmap[y].subarray(xMin, xMax));\n          }\n          newSymbols.push(symbolBitmap);\n          xMin = xMax;\n        }\n      }\n    }\n  }\n  const exportedSymbols = [],\n    flags = [];\n  let currentFlag = false,\n    i,\n    ii;\n  const totalSymbolsLength = symbols.length + numberOfNewSymbols;\n  while (flags.length < totalSymbolsLength) {\n    let runLength = huffman ? tableB1.decode(huffmanInput) : decodeInteger(contextCache, \"IAEX\", decoder);\n    while (runLength--) {\n      flags.push(currentFlag);\n    }\n    currentFlag = !currentFlag;\n  }\n  for (i = 0, ii = symbols.length; i < ii; i++) {\n    if (flags[i]) {\n      exportedSymbols.push(symbols[i]);\n    }\n  }\n  for (let j = 0; j < numberOfNewSymbols; i++, j++) {\n    if (flags[i]) {\n      exportedSymbols.push(newSymbols[j]);\n    }\n  }\n  return exportedSymbols;\n}\nfunction decodeTextRegion(huffman, refinement, width, height, defaultPixelValue, numberOfSymbolInstances, stripSize, inputSymbols, symbolCodeLength, transposed, dsOffset, referenceCorner, combinationOperator, huffmanTables, refinementTemplateIndex, refinementAt, decodingContext, logStripSize, huffmanInput) {\n  if (huffman && refinement) {\n    throw new Jbig2Error(\"refinement with Huffman is not supported\");\n  }\n  const bitmap = [];\n  let i, row;\n  for (i = 0; i < height; i++) {\n    row = new Uint8Array(width);\n    if (defaultPixelValue) {\n      for (let j = 0; j < width; j++) {\n        row[j] = defaultPixelValue;\n      }\n    }\n    bitmap.push(row);\n  }\n  const decoder = decodingContext.decoder;\n  const contextCache = decodingContext.contextCache;\n  let stripT = huffman ? -huffmanTables.tableDeltaT.decode(huffmanInput) : -decodeInteger(contextCache, \"IADT\", decoder);\n  let firstS = 0;\n  i = 0;\n  while (i < numberOfSymbolInstances) {\n    const deltaT = huffman ? huffmanTables.tableDeltaT.decode(huffmanInput) : decodeInteger(contextCache, \"IADT\", decoder);\n    stripT += deltaT;\n    const deltaFirstS = huffman ? huffmanTables.tableFirstS.decode(huffmanInput) : decodeInteger(contextCache, \"IAFS\", decoder);\n    firstS += deltaFirstS;\n    let currentS = firstS;\n    do {\n      let currentT = 0;\n      if (stripSize > 1) {\n        currentT = huffman ? huffmanInput.readBits(logStripSize) : decodeInteger(contextCache, \"IAIT\", decoder);\n      }\n      const t = stripSize * stripT + currentT;\n      const symbolId = huffman ? huffmanTables.symbolIDTable.decode(huffmanInput) : decodeIAID(contextCache, decoder, symbolCodeLength);\n      const applyRefinement = refinement && (huffman ? huffmanInput.readBit() : decodeInteger(contextCache, \"IARI\", decoder));\n      let symbolBitmap = inputSymbols[symbolId];\n      let symbolWidth = symbolBitmap[0].length;\n      let symbolHeight = symbolBitmap.length;\n      if (applyRefinement) {\n        const rdw = decodeInteger(contextCache, \"IARDW\", decoder);\n        const rdh = decodeInteger(contextCache, \"IARDH\", decoder);\n        const rdx = decodeInteger(contextCache, \"IARDX\", decoder);\n        const rdy = decodeInteger(contextCache, \"IARDY\", decoder);\n        symbolWidth += rdw;\n        symbolHeight += rdh;\n        symbolBitmap = decodeRefinement(symbolWidth, symbolHeight, refinementTemplateIndex, symbolBitmap, (rdw >> 1) + rdx, (rdh >> 1) + rdy, false, refinementAt, decodingContext);\n      }\n      const offsetT = t - (referenceCorner & 1 ? 0 : symbolHeight - 1);\n      const offsetS = currentS - (referenceCorner & 2 ? symbolWidth - 1 : 0);\n      let s2, t2, symbolRow;\n      if (transposed) {\n        for (s2 = 0; s2 < symbolHeight; s2++) {\n          row = bitmap[offsetS + s2];\n          if (!row) {\n            continue;\n          }\n          symbolRow = symbolBitmap[s2];\n          const maxWidth = Math.min(width - offsetT, symbolWidth);\n          switch (combinationOperator) {\n            case 0:\n              for (t2 = 0; t2 < maxWidth; t2++) {\n                row[offsetT + t2] |= symbolRow[t2];\n              }\n              break;\n            case 2:\n              for (t2 = 0; t2 < maxWidth; t2++) {\n                row[offsetT + t2] ^= symbolRow[t2];\n              }\n              break;\n            default:\n              throw new Jbig2Error(`operator ${combinationOperator} is not supported`);\n          }\n        }\n        currentS += symbolHeight - 1;\n      } else {\n        for (t2 = 0; t2 < symbolHeight; t2++) {\n          row = bitmap[offsetT + t2];\n          if (!row) {\n            continue;\n          }\n          symbolRow = symbolBitmap[t2];\n          switch (combinationOperator) {\n            case 0:\n              for (s2 = 0; s2 < symbolWidth; s2++) {\n                row[offsetS + s2] |= symbolRow[s2];\n              }\n              break;\n            case 2:\n              for (s2 = 0; s2 < symbolWidth; s2++) {\n                row[offsetS + s2] ^= symbolRow[s2];\n              }\n              break;\n            default:\n              throw new Jbig2Error(`operator ${combinationOperator} is not supported`);\n          }\n        }\n        currentS += symbolWidth - 1;\n      }\n      i++;\n      const deltaS = huffman ? huffmanTables.tableDeltaS.decode(huffmanInput) : decodeInteger(contextCache, \"IADS\", decoder);\n      if (deltaS === null) {\n        break;\n      }\n      currentS += deltaS + dsOffset;\n    } while (true);\n  }\n  return bitmap;\n}\nfunction decodePatternDictionary(mmr, patternWidth, patternHeight, maxPatternIndex, template, decodingContext) {\n  const at = [];\n  if (!mmr) {\n    at.push({\n      x: -patternWidth,\n      y: 0\n    });\n    if (template === 0) {\n      at.push({\n        x: -3,\n        y: -1\n      }, {\n        x: 2,\n        y: -2\n      }, {\n        x: -2,\n        y: -2\n      });\n    }\n  }\n  const collectiveWidth = (maxPatternIndex + 1) * patternWidth;\n  const collectiveBitmap = decodeBitmap(mmr, collectiveWidth, patternHeight, template, false, null, at, decodingContext);\n  const patterns = [];\n  for (let i = 0; i <= maxPatternIndex; i++) {\n    const patternBitmap = [];\n    const xMin = patternWidth * i;\n    const xMax = xMin + patternWidth;\n    for (let y = 0; y < patternHeight; y++) {\n      patternBitmap.push(collectiveBitmap[y].subarray(xMin, xMax));\n    }\n    patterns.push(patternBitmap);\n  }\n  return patterns;\n}\nfunction decodeHalftoneRegion(mmr, patterns, template, regionWidth, regionHeight, defaultPixelValue, enableSkip, combinationOperator, gridWidth, gridHeight, gridOffsetX, gridOffsetY, gridVectorX, gridVectorY, decodingContext) {\n  const skip = null;\n  if (enableSkip) {\n    throw new Jbig2Error(\"skip is not supported\");\n  }\n  if (combinationOperator !== 0) {\n    throw new Jbig2Error(`operator \"${combinationOperator}\" is not supported in halftone region`);\n  }\n  const regionBitmap = [];\n  let i, j, row;\n  for (i = 0; i < regionHeight; i++) {\n    row = new Uint8Array(regionWidth);\n    if (defaultPixelValue) {\n      for (j = 0; j < regionWidth; j++) {\n        row[j] = defaultPixelValue;\n      }\n    }\n    regionBitmap.push(row);\n  }\n  const numberOfPatterns = patterns.length;\n  const pattern0 = patterns[0];\n  const patternWidth = pattern0[0].length,\n    patternHeight = pattern0.length;\n  const bitsPerValue = log2(numberOfPatterns);\n  const at = [];\n  if (!mmr) {\n    at.push({\n      x: template <= 1 ? 3 : 2,\n      y: -1\n    });\n    if (template === 0) {\n      at.push({\n        x: -3,\n        y: -1\n      }, {\n        x: 2,\n        y: -2\n      }, {\n        x: -2,\n        y: -2\n      });\n    }\n  }\n  const grayScaleBitPlanes = [];\n  let mmrInput, bitmap;\n  if (mmr) {\n    mmrInput = new Reader(decodingContext.data, decodingContext.start, decodingContext.end);\n  }\n  for (i = bitsPerValue - 1; i >= 0; i--) {\n    if (mmr) {\n      bitmap = decodeMMRBitmap(mmrInput, gridWidth, gridHeight, true);\n    } else {\n      bitmap = decodeBitmap(false, gridWidth, gridHeight, template, false, skip, at, decodingContext);\n    }\n    grayScaleBitPlanes[i] = bitmap;\n  }\n  let mg, ng, bit, patternIndex, patternBitmap, x, y, patternRow, regionRow;\n  for (mg = 0; mg < gridHeight; mg++) {\n    for (ng = 0; ng < gridWidth; ng++) {\n      bit = 0;\n      patternIndex = 0;\n      for (j = bitsPerValue - 1; j >= 0; j--) {\n        bit ^= grayScaleBitPlanes[j][mg][ng];\n        patternIndex |= bit << j;\n      }\n      patternBitmap = patterns[patternIndex];\n      x = gridOffsetX + mg * gridVectorY + ng * gridVectorX >> 8;\n      y = gridOffsetY + mg * gridVectorX - ng * gridVectorY >> 8;\n      if (x >= 0 && x + patternWidth <= regionWidth && y >= 0 && y + patternHeight <= regionHeight) {\n        for (i = 0; i < patternHeight; i++) {\n          regionRow = regionBitmap[y + i];\n          patternRow = patternBitmap[i];\n          for (j = 0; j < patternWidth; j++) {\n            regionRow[x + j] |= patternRow[j];\n          }\n        }\n      } else {\n        let regionX, regionY;\n        for (i = 0; i < patternHeight; i++) {\n          regionY = y + i;\n          if (regionY < 0 || regionY >= regionHeight) {\n            continue;\n          }\n          regionRow = regionBitmap[regionY];\n          patternRow = patternBitmap[i];\n          for (j = 0; j < patternWidth; j++) {\n            regionX = x + j;\n            if (regionX >= 0 && regionX < regionWidth) {\n              regionRow[regionX] |= patternRow[j];\n            }\n          }\n        }\n      }\n    }\n  }\n  return regionBitmap;\n}\nfunction readSegmentHeader(data, start) {\n  const segmentHeader = {};\n  segmentHeader.number = readUint32(data, start);\n  const flags = data[start + 4];\n  const segmentType = flags & 0x3f;\n  if (!SegmentTypes[segmentType]) {\n    throw new Jbig2Error(\"invalid segment type: \" + segmentType);\n  }\n  segmentHeader.type = segmentType;\n  segmentHeader.typeName = SegmentTypes[segmentType];\n  segmentHeader.deferredNonRetain = !!(flags & 0x80);\n  const pageAssociationFieldSize = !!(flags & 0x40);\n  const referredFlags = data[start + 5];\n  let referredToCount = referredFlags >> 5 & 7;\n  const retainBits = [referredFlags & 31];\n  let position = start + 6;\n  if (referredFlags === 7) {\n    referredToCount = readUint32(data, position - 1) & 0x1fffffff;\n    position += 3;\n    let bytes = referredToCount + 7 >> 3;\n    retainBits[0] = data[position++];\n    while (--bytes > 0) {\n      retainBits.push(data[position++]);\n    }\n  } else if (referredFlags === 5 || referredFlags === 6) {\n    throw new Jbig2Error(\"invalid referred-to flags\");\n  }\n  segmentHeader.retainBits = retainBits;\n  let referredToSegmentNumberSize = 4;\n  if (segmentHeader.number <= 256) {\n    referredToSegmentNumberSize = 1;\n  } else if (segmentHeader.number <= 65536) {\n    referredToSegmentNumberSize = 2;\n  }\n  const referredTo = [];\n  let i, ii;\n  for (i = 0; i < referredToCount; i++) {\n    let number;\n    if (referredToSegmentNumberSize === 1) {\n      number = data[position];\n    } else if (referredToSegmentNumberSize === 2) {\n      number = readUint16(data, position);\n    } else {\n      number = readUint32(data, position);\n    }\n    referredTo.push(number);\n    position += referredToSegmentNumberSize;\n  }\n  segmentHeader.referredTo = referredTo;\n  if (!pageAssociationFieldSize) {\n    segmentHeader.pageAssociation = data[position++];\n  } else {\n    segmentHeader.pageAssociation = readUint32(data, position);\n    position += 4;\n  }\n  segmentHeader.length = readUint32(data, position);\n  position += 4;\n  if (segmentHeader.length === 0xffffffff) {\n    if (segmentType === 38) {\n      const genericRegionInfo = readRegionSegmentInformation(data, position);\n      const genericRegionSegmentFlags = data[position + RegionSegmentInformationFieldLength];\n      const genericRegionMmr = !!(genericRegionSegmentFlags & 1);\n      const searchPatternLength = 6;\n      const searchPattern = new Uint8Array(searchPatternLength);\n      if (!genericRegionMmr) {\n        searchPattern[0] = 0xff;\n        searchPattern[1] = 0xac;\n      }\n      searchPattern[2] = genericRegionInfo.height >>> 24 & 0xff;\n      searchPattern[3] = genericRegionInfo.height >> 16 & 0xff;\n      searchPattern[4] = genericRegionInfo.height >> 8 & 0xff;\n      searchPattern[5] = genericRegionInfo.height & 0xff;\n      for (i = position, ii = data.length; i < ii; i++) {\n        let j = 0;\n        while (j < searchPatternLength && searchPattern[j] === data[i + j]) {\n          j++;\n        }\n        if (j === searchPatternLength) {\n          segmentHeader.length = i + searchPatternLength;\n          break;\n        }\n      }\n      if (segmentHeader.length === 0xffffffff) {\n        throw new Jbig2Error(\"segment end was not found\");\n      }\n    } else {\n      throw new Jbig2Error(\"invalid unknown segment length\");\n    }\n  }\n  segmentHeader.headerEnd = position;\n  return segmentHeader;\n}\nfunction readSegments(header, data, start, end) {\n  const segments = [];\n  let position = start;\n  while (position < end) {\n    const segmentHeader = readSegmentHeader(data, position);\n    position = segmentHeader.headerEnd;\n    const segment = {\n      header: segmentHeader,\n      data\n    };\n    if (!header.randomAccess) {\n      segment.start = position;\n      position += segmentHeader.length;\n      segment.end = position;\n    }\n    segments.push(segment);\n    if (segmentHeader.type === 51) {\n      break;\n    }\n  }\n  if (header.randomAccess) {\n    for (let i = 0, ii = segments.length; i < ii; i++) {\n      segments[i].start = position;\n      position += segments[i].header.length;\n      segments[i].end = position;\n    }\n  }\n  return segments;\n}\nfunction readRegionSegmentInformation(data, start) {\n  return {\n    width: readUint32(data, start),\n    height: readUint32(data, start + 4),\n    x: readUint32(data, start + 8),\n    y: readUint32(data, start + 12),\n    combinationOperator: data[start + 16] & 7\n  };\n}\nconst RegionSegmentInformationFieldLength = 17;\nfunction processSegment(segment, visitor) {\n  const header = segment.header;\n  const data = segment.data,\n    end = segment.end;\n  let position = segment.start;\n  let args, at, i, atLength;\n  switch (header.type) {\n    case 0:\n      const dictionary = {};\n      const dictionaryFlags = readUint16(data, position);\n      dictionary.huffman = !!(dictionaryFlags & 1);\n      dictionary.refinement = !!(dictionaryFlags & 2);\n      dictionary.huffmanDHSelector = dictionaryFlags >> 2 & 3;\n      dictionary.huffmanDWSelector = dictionaryFlags >> 4 & 3;\n      dictionary.bitmapSizeSelector = dictionaryFlags >> 6 & 1;\n      dictionary.aggregationInstancesSelector = dictionaryFlags >> 7 & 1;\n      dictionary.bitmapCodingContextUsed = !!(dictionaryFlags & 256);\n      dictionary.bitmapCodingContextRetained = !!(dictionaryFlags & 512);\n      dictionary.template = dictionaryFlags >> 10 & 3;\n      dictionary.refinementTemplate = dictionaryFlags >> 12 & 1;\n      position += 2;\n      if (!dictionary.huffman) {\n        atLength = dictionary.template === 0 ? 4 : 1;\n        at = [];\n        for (i = 0; i < atLength; i++) {\n          at.push({\n            x: readInt8(data, position),\n            y: readInt8(data, position + 1)\n          });\n          position += 2;\n        }\n        dictionary.at = at;\n      }\n      if (dictionary.refinement && !dictionary.refinementTemplate) {\n        at = [];\n        for (i = 0; i < 2; i++) {\n          at.push({\n            x: readInt8(data, position),\n            y: readInt8(data, position + 1)\n          });\n          position += 2;\n        }\n        dictionary.refinementAt = at;\n      }\n      dictionary.numberOfExportedSymbols = readUint32(data, position);\n      position += 4;\n      dictionary.numberOfNewSymbols = readUint32(data, position);\n      position += 4;\n      args = [dictionary, header.number, header.referredTo, data, position, end];\n      break;\n    case 6:\n    case 7:\n      const textRegion = {};\n      textRegion.info = readRegionSegmentInformation(data, position);\n      position += RegionSegmentInformationFieldLength;\n      const textRegionSegmentFlags = readUint16(data, position);\n      position += 2;\n      textRegion.huffman = !!(textRegionSegmentFlags & 1);\n      textRegion.refinement = !!(textRegionSegmentFlags & 2);\n      textRegion.logStripSize = textRegionSegmentFlags >> 2 & 3;\n      textRegion.stripSize = 1 << textRegion.logStripSize;\n      textRegion.referenceCorner = textRegionSegmentFlags >> 4 & 3;\n      textRegion.transposed = !!(textRegionSegmentFlags & 64);\n      textRegion.combinationOperator = textRegionSegmentFlags >> 7 & 3;\n      textRegion.defaultPixelValue = textRegionSegmentFlags >> 9 & 1;\n      textRegion.dsOffset = textRegionSegmentFlags << 17 >> 27;\n      textRegion.refinementTemplate = textRegionSegmentFlags >> 15 & 1;\n      if (textRegion.huffman) {\n        const textRegionHuffmanFlags = readUint16(data, position);\n        position += 2;\n        textRegion.huffmanFS = textRegionHuffmanFlags & 3;\n        textRegion.huffmanDS = textRegionHuffmanFlags >> 2 & 3;\n        textRegion.huffmanDT = textRegionHuffmanFlags >> 4 & 3;\n        textRegion.huffmanRefinementDW = textRegionHuffmanFlags >> 6 & 3;\n        textRegion.huffmanRefinementDH = textRegionHuffmanFlags >> 8 & 3;\n        textRegion.huffmanRefinementDX = textRegionHuffmanFlags >> 10 & 3;\n        textRegion.huffmanRefinementDY = textRegionHuffmanFlags >> 12 & 3;\n        textRegion.huffmanRefinementSizeSelector = !!(textRegionHuffmanFlags & 0x4000);\n      }\n      if (textRegion.refinement && !textRegion.refinementTemplate) {\n        at = [];\n        for (i = 0; i < 2; i++) {\n          at.push({\n            x: readInt8(data, position),\n            y: readInt8(data, position + 1)\n          });\n          position += 2;\n        }\n        textRegion.refinementAt = at;\n      }\n      textRegion.numberOfSymbolInstances = readUint32(data, position);\n      position += 4;\n      args = [textRegion, header.referredTo, data, position, end];\n      break;\n    case 16:\n      const patternDictionary = {};\n      const patternDictionaryFlags = data[position++];\n      patternDictionary.mmr = !!(patternDictionaryFlags & 1);\n      patternDictionary.template = patternDictionaryFlags >> 1 & 3;\n      patternDictionary.patternWidth = data[position++];\n      patternDictionary.patternHeight = data[position++];\n      patternDictionary.maxPatternIndex = readUint32(data, position);\n      position += 4;\n      args = [patternDictionary, header.number, data, position, end];\n      break;\n    case 22:\n    case 23:\n      const halftoneRegion = {};\n      halftoneRegion.info = readRegionSegmentInformation(data, position);\n      position += RegionSegmentInformationFieldLength;\n      const halftoneRegionFlags = data[position++];\n      halftoneRegion.mmr = !!(halftoneRegionFlags & 1);\n      halftoneRegion.template = halftoneRegionFlags >> 1 & 3;\n      halftoneRegion.enableSkip = !!(halftoneRegionFlags & 8);\n      halftoneRegion.combinationOperator = halftoneRegionFlags >> 4 & 7;\n      halftoneRegion.defaultPixelValue = halftoneRegionFlags >> 7 & 1;\n      halftoneRegion.gridWidth = readUint32(data, position);\n      position += 4;\n      halftoneRegion.gridHeight = readUint32(data, position);\n      position += 4;\n      halftoneRegion.gridOffsetX = readUint32(data, position) & 0xffffffff;\n      position += 4;\n      halftoneRegion.gridOffsetY = readUint32(data, position) & 0xffffffff;\n      position += 4;\n      halftoneRegion.gridVectorX = readUint16(data, position);\n      position += 2;\n      halftoneRegion.gridVectorY = readUint16(data, position);\n      position += 2;\n      args = [halftoneRegion, header.referredTo, data, position, end];\n      break;\n    case 38:\n    case 39:\n      const genericRegion = {};\n      genericRegion.info = readRegionSegmentInformation(data, position);\n      position += RegionSegmentInformationFieldLength;\n      const genericRegionSegmentFlags = data[position++];\n      genericRegion.mmr = !!(genericRegionSegmentFlags & 1);\n      genericRegion.template = genericRegionSegmentFlags >> 1 & 3;\n      genericRegion.prediction = !!(genericRegionSegmentFlags & 8);\n      if (!genericRegion.mmr) {\n        atLength = genericRegion.template === 0 ? 4 : 1;\n        at = [];\n        for (i = 0; i < atLength; i++) {\n          at.push({\n            x: readInt8(data, position),\n            y: readInt8(data, position + 1)\n          });\n          position += 2;\n        }\n        genericRegion.at = at;\n      }\n      args = [genericRegion, data, position, end];\n      break;\n    case 48:\n      const pageInfo = {\n        width: readUint32(data, position),\n        height: readUint32(data, position + 4),\n        resolutionX: readUint32(data, position + 8),\n        resolutionY: readUint32(data, position + 12)\n      };\n      if (pageInfo.height === 0xffffffff) {\n        delete pageInfo.height;\n      }\n      const pageSegmentFlags = data[position + 16];\n      readUint16(data, position + 17);\n      pageInfo.lossless = !!(pageSegmentFlags & 1);\n      pageInfo.refinement = !!(pageSegmentFlags & 2);\n      pageInfo.defaultPixelValue = pageSegmentFlags >> 2 & 1;\n      pageInfo.combinationOperator = pageSegmentFlags >> 3 & 3;\n      pageInfo.requiresBuffer = !!(pageSegmentFlags & 32);\n      pageInfo.combinationOperatorOverride = !!(pageSegmentFlags & 64);\n      args = [pageInfo];\n      break;\n    case 49:\n      break;\n    case 50:\n      break;\n    case 51:\n      break;\n    case 53:\n      args = [header.number, data, position, end];\n      break;\n    case 62:\n      break;\n    default:\n      throw new Jbig2Error(`segment type ${header.typeName}(${header.type}) is not implemented`);\n  }\n  const callbackName = \"on\" + header.typeName;\n  if (callbackName in visitor) {\n    visitor[callbackName].apply(visitor, args);\n  }\n}\nfunction processSegments(segments, visitor) {\n  for (let i = 0, ii = segments.length; i < ii; i++) {\n    processSegment(segments[i], visitor);\n  }\n}\nfunction parseJbig2Chunks(chunks) {\n  const visitor = new SimpleSegmentVisitor();\n  for (let i = 0, ii = chunks.length; i < ii; i++) {\n    const chunk = chunks[i];\n    const segments = readSegments({}, chunk.data, chunk.start, chunk.end);\n    processSegments(segments, visitor);\n  }\n  return visitor.buffer;\n}\nfunction parseJbig2(data) {\n  throw new Error(\"Not implemented: parseJbig2\");\n}\nclass SimpleSegmentVisitor {\n  onPageInformation(info) {\n    this.currentPageInfo = info;\n    const rowSize = info.width + 7 >> 3;\n    const buffer = new Uint8ClampedArray(rowSize * info.height);\n    if (info.defaultPixelValue) {\n      buffer.fill(0xff);\n    }\n    this.buffer = buffer;\n  }\n  drawBitmap(regionInfo, bitmap) {\n    const pageInfo = this.currentPageInfo;\n    const width = regionInfo.width,\n      height = regionInfo.height;\n    const rowSize = pageInfo.width + 7 >> 3;\n    const combinationOperator = pageInfo.combinationOperatorOverride ? regionInfo.combinationOperator : pageInfo.combinationOperator;\n    const buffer = this.buffer;\n    const mask0 = 128 >> (regionInfo.x & 7);\n    let offset0 = regionInfo.y * rowSize + (regionInfo.x >> 3);\n    let i, j, mask, offset;\n    switch (combinationOperator) {\n      case 0:\n        for (i = 0; i < height; i++) {\n          mask = mask0;\n          offset = offset0;\n          for (j = 0; j < width; j++) {\n            if (bitmap[i][j]) {\n              buffer[offset] |= mask;\n            }\n            mask >>= 1;\n            if (!mask) {\n              mask = 128;\n              offset++;\n            }\n          }\n          offset0 += rowSize;\n        }\n        break;\n      case 2:\n        for (i = 0; i < height; i++) {\n          mask = mask0;\n          offset = offset0;\n          for (j = 0; j < width; j++) {\n            if (bitmap[i][j]) {\n              buffer[offset] ^= mask;\n            }\n            mask >>= 1;\n            if (!mask) {\n              mask = 128;\n              offset++;\n            }\n          }\n          offset0 += rowSize;\n        }\n        break;\n      default:\n        throw new Jbig2Error(`operator ${combinationOperator} is not supported`);\n    }\n  }\n  onImmediateGenericRegion(region, data, start, end) {\n    const regionInfo = region.info;\n    const decodingContext = new DecodingContext(data, start, end);\n    const bitmap = decodeBitmap(region.mmr, regionInfo.width, regionInfo.height, region.template, region.prediction, null, region.at, decodingContext);\n    this.drawBitmap(regionInfo, bitmap);\n  }\n  onImmediateLosslessGenericRegion() {\n    this.onImmediateGenericRegion(...arguments);\n  }\n  onSymbolDictionary(dictionary, currentSegment, referredSegments, data, start, end) {\n    let huffmanTables, huffmanInput;\n    if (dictionary.huffman) {\n      huffmanTables = getSymbolDictionaryHuffmanTables(dictionary, referredSegments, this.customTables);\n      huffmanInput = new Reader(data, start, end);\n    }\n    let symbols = this.symbols;\n    if (!symbols) {\n      this.symbols = symbols = {};\n    }\n    const inputSymbols = [];\n    for (const referredSegment of referredSegments) {\n      const referredSymbols = symbols[referredSegment];\n      if (referredSymbols) {\n        inputSymbols.push(...referredSymbols);\n      }\n    }\n    const decodingContext = new DecodingContext(data, start, end);\n    symbols[currentSegment] = decodeSymbolDictionary(dictionary.huffman, dictionary.refinement, inputSymbols, dictionary.numberOfNewSymbols, dictionary.numberOfExportedSymbols, huffmanTables, dictionary.template, dictionary.at, dictionary.refinementTemplate, dictionary.refinementAt, decodingContext, huffmanInput);\n  }\n  onImmediateTextRegion(region, referredSegments, data, start, end) {\n    const regionInfo = region.info;\n    let huffmanTables, huffmanInput;\n    const symbols = this.symbols;\n    const inputSymbols = [];\n    for (const referredSegment of referredSegments) {\n      const referredSymbols = symbols[referredSegment];\n      if (referredSymbols) {\n        inputSymbols.push(...referredSymbols);\n      }\n    }\n    const symbolCodeLength = log2(inputSymbols.length);\n    if (region.huffman) {\n      huffmanInput = new Reader(data, start, end);\n      huffmanTables = getTextRegionHuffmanTables(region, referredSegments, this.customTables, inputSymbols.length, huffmanInput);\n    }\n    const decodingContext = new DecodingContext(data, start, end);\n    const bitmap = decodeTextRegion(region.huffman, region.refinement, regionInfo.width, regionInfo.height, region.defaultPixelValue, region.numberOfSymbolInstances, region.stripSize, inputSymbols, symbolCodeLength, region.transposed, region.dsOffset, region.referenceCorner, region.combinationOperator, huffmanTables, region.refinementTemplate, region.refinementAt, decodingContext, region.logStripSize, huffmanInput);\n    this.drawBitmap(regionInfo, bitmap);\n  }\n  onImmediateLosslessTextRegion() {\n    this.onImmediateTextRegion(...arguments);\n  }\n  onPatternDictionary(dictionary, currentSegment, data, start, end) {\n    let patterns = this.patterns;\n    if (!patterns) {\n      this.patterns = patterns = {};\n    }\n    const decodingContext = new DecodingContext(data, start, end);\n    patterns[currentSegment] = decodePatternDictionary(dictionary.mmr, dictionary.patternWidth, dictionary.patternHeight, dictionary.maxPatternIndex, dictionary.template, decodingContext);\n  }\n  onImmediateHalftoneRegion(region, referredSegments, data, start, end) {\n    const patterns = this.patterns[referredSegments[0]];\n    const regionInfo = region.info;\n    const decodingContext = new DecodingContext(data, start, end);\n    const bitmap = decodeHalftoneRegion(region.mmr, patterns, region.template, regionInfo.width, regionInfo.height, region.defaultPixelValue, region.enableSkip, region.combinationOperator, region.gridWidth, region.gridHeight, region.gridOffsetX, region.gridOffsetY, region.gridVectorX, region.gridVectorY, decodingContext);\n    this.drawBitmap(regionInfo, bitmap);\n  }\n  onImmediateLosslessHalftoneRegion() {\n    this.onImmediateHalftoneRegion(...arguments);\n  }\n  onTables(currentSegment, data, start, end) {\n    let customTables = this.customTables;\n    if (!customTables) {\n      this.customTables = customTables = {};\n    }\n    customTables[currentSegment] = decodeTablesSegment(data, start, end);\n  }\n}\nclass HuffmanLine {\n  constructor(lineData) {\n    if (lineData.length === 2) {\n      this.isOOB = true;\n      this.rangeLow = 0;\n      this.prefixLength = lineData[0];\n      this.rangeLength = 0;\n      this.prefixCode = lineData[1];\n      this.isLowerRange = false;\n    } else {\n      this.isOOB = false;\n      this.rangeLow = lineData[0];\n      this.prefixLength = lineData[1];\n      this.rangeLength = lineData[2];\n      this.prefixCode = lineData[3];\n      this.isLowerRange = lineData[4] === \"lower\";\n    }\n  }\n}\nclass HuffmanTreeNode {\n  constructor(line) {\n    this.children = [];\n    if (line) {\n      this.isLeaf = true;\n      this.rangeLength = line.rangeLength;\n      this.rangeLow = line.rangeLow;\n      this.isLowerRange = line.isLowerRange;\n      this.isOOB = line.isOOB;\n    } else {\n      this.isLeaf = false;\n    }\n  }\n  buildTree(line, shift) {\n    const bit = line.prefixCode >> shift & 1;\n    if (shift <= 0) {\n      this.children[bit] = new HuffmanTreeNode(line);\n    } else {\n      let node = this.children[bit];\n      if (!node) {\n        this.children[bit] = node = new HuffmanTreeNode(null);\n      }\n      node.buildTree(line, shift - 1);\n    }\n  }\n  decodeNode(reader) {\n    if (this.isLeaf) {\n      if (this.isOOB) {\n        return null;\n      }\n      const htOffset = reader.readBits(this.rangeLength);\n      return this.rangeLow + (this.isLowerRange ? -htOffset : htOffset);\n    }\n    const node = this.children[reader.readBit()];\n    if (!node) {\n      throw new Jbig2Error(\"invalid Huffman data\");\n    }\n    return node.decodeNode(reader);\n  }\n}\nclass HuffmanTable {\n  constructor(lines, prefixCodesDone) {\n    if (!prefixCodesDone) {\n      this.assignPrefixCodes(lines);\n    }\n    this.rootNode = new HuffmanTreeNode(null);\n    for (let i = 0, ii = lines.length; i < ii; i++) {\n      const line = lines[i];\n      if (line.prefixLength > 0) {\n        this.rootNode.buildTree(line, line.prefixLength - 1);\n      }\n    }\n  }\n  decode(reader) {\n    return this.rootNode.decodeNode(reader);\n  }\n  assignPrefixCodes(lines) {\n    const linesLength = lines.length;\n    let prefixLengthMax = 0;\n    for (let i = 0; i < linesLength; i++) {\n      prefixLengthMax = Math.max(prefixLengthMax, lines[i].prefixLength);\n    }\n    const histogram = new Uint32Array(prefixLengthMax + 1);\n    for (let i = 0; i < linesLength; i++) {\n      histogram[lines[i].prefixLength]++;\n    }\n    let currentLength = 1,\n      firstCode = 0,\n      currentCode,\n      currentTemp,\n      line;\n    histogram[0] = 0;\n    while (currentLength <= prefixLengthMax) {\n      firstCode = firstCode + histogram[currentLength - 1] << 1;\n      currentCode = firstCode;\n      currentTemp = 0;\n      while (currentTemp < linesLength) {\n        line = lines[currentTemp];\n        if (line.prefixLength === currentLength) {\n          line.prefixCode = currentCode;\n          currentCode++;\n        }\n        currentTemp++;\n      }\n      currentLength++;\n    }\n  }\n}\nfunction decodeTablesSegment(data, start, end) {\n  const flags = data[start];\n  const lowestValue = readUint32(data, start + 1) & 0xffffffff;\n  const highestValue = readUint32(data, start + 5) & 0xffffffff;\n  const reader = new Reader(data, start + 9, end);\n  const prefixSizeBits = (flags >> 1 & 7) + 1;\n  const rangeSizeBits = (flags >> 4 & 7) + 1;\n  const lines = [];\n  let prefixLength,\n    rangeLength,\n    currentRangeLow = lowestValue;\n  do {\n    prefixLength = reader.readBits(prefixSizeBits);\n    rangeLength = reader.readBits(rangeSizeBits);\n    lines.push(new HuffmanLine([currentRangeLow, prefixLength, rangeLength, 0]));\n    currentRangeLow += 1 << rangeLength;\n  } while (currentRangeLow < highestValue);\n  prefixLength = reader.readBits(prefixSizeBits);\n  lines.push(new HuffmanLine([lowestValue - 1, prefixLength, 32, 0, \"lower\"]));\n  prefixLength = reader.readBits(prefixSizeBits);\n  lines.push(new HuffmanLine([highestValue, prefixLength, 32, 0]));\n  if (flags & 1) {\n    prefixLength = reader.readBits(prefixSizeBits);\n    lines.push(new HuffmanLine([prefixLength, 0]));\n  }\n  return new HuffmanTable(lines, false);\n}\nconst standardTablesCache = {};\nfunction getStandardTable(number) {\n  let table = standardTablesCache[number];\n  if (table) {\n    return table;\n  }\n  let lines;\n  switch (number) {\n    case 1:\n      lines = [[0, 1, 4, 0x0], [16, 2, 8, 0x2], [272, 3, 16, 0x6], [65808, 3, 32, 0x7]];\n      break;\n    case 2:\n      lines = [[0, 1, 0, 0x0], [1, 2, 0, 0x2], [2, 3, 0, 0x6], [3, 4, 3, 0xe], [11, 5, 6, 0x1e], [75, 6, 32, 0x3e], [6, 0x3f]];\n      break;\n    case 3:\n      lines = [[-256, 8, 8, 0xfe], [0, 1, 0, 0x0], [1, 2, 0, 0x2], [2, 3, 0, 0x6], [3, 4, 3, 0xe], [11, 5, 6, 0x1e], [-257, 8, 32, 0xff, \"lower\"], [75, 7, 32, 0x7e], [6, 0x3e]];\n      break;\n    case 4:\n      lines = [[1, 1, 0, 0x0], [2, 2, 0, 0x2], [3, 3, 0, 0x6], [4, 4, 3, 0xe], [12, 5, 6, 0x1e], [76, 5, 32, 0x1f]];\n      break;\n    case 5:\n      lines = [[-255, 7, 8, 0x7e], [1, 1, 0, 0x0], [2, 2, 0, 0x2], [3, 3, 0, 0x6], [4, 4, 3, 0xe], [12, 5, 6, 0x1e], [-256, 7, 32, 0x7f, \"lower\"], [76, 6, 32, 0x3e]];\n      break;\n    case 6:\n      lines = [[-2048, 5, 10, 0x1c], [-1024, 4, 9, 0x8], [-512, 4, 8, 0x9], [-256, 4, 7, 0xa], [-128, 5, 6, 0x1d], [-64, 5, 5, 0x1e], [-32, 4, 5, 0xb], [0, 2, 7, 0x0], [128, 3, 7, 0x2], [256, 3, 8, 0x3], [512, 4, 9, 0xc], [1024, 4, 10, 0xd], [-2049, 6, 32, 0x3e, \"lower\"], [2048, 6, 32, 0x3f]];\n      break;\n    case 7:\n      lines = [[-1024, 4, 9, 0x8], [-512, 3, 8, 0x0], [-256, 4, 7, 0x9], [-128, 5, 6, 0x1a], [-64, 5, 5, 0x1b], [-32, 4, 5, 0xa], [0, 4, 5, 0xb], [32, 5, 5, 0x1c], [64, 5, 6, 0x1d], [128, 4, 7, 0xc], [256, 3, 8, 0x1], [512, 3, 9, 0x2], [1024, 3, 10, 0x3], [-1025, 5, 32, 0x1e, \"lower\"], [2048, 5, 32, 0x1f]];\n      break;\n    case 8:\n      lines = [[-15, 8, 3, 0xfc], [-7, 9, 1, 0x1fc], [-5, 8, 1, 0xfd], [-3, 9, 0, 0x1fd], [-2, 7, 0, 0x7c], [-1, 4, 0, 0xa], [0, 2, 1, 0x0], [2, 5, 0, 0x1a], [3, 6, 0, 0x3a], [4, 3, 4, 0x4], [20, 6, 1, 0x3b], [22, 4, 4, 0xb], [38, 4, 5, 0xc], [70, 5, 6, 0x1b], [134, 5, 7, 0x1c], [262, 6, 7, 0x3c], [390, 7, 8, 0x7d], [646, 6, 10, 0x3d], [-16, 9, 32, 0x1fe, \"lower\"], [1670, 9, 32, 0x1ff], [2, 0x1]];\n      break;\n    case 9:\n      lines = [[-31, 8, 4, 0xfc], [-15, 9, 2, 0x1fc], [-11, 8, 2, 0xfd], [-7, 9, 1, 0x1fd], [-5, 7, 1, 0x7c], [-3, 4, 1, 0xa], [-1, 3, 1, 0x2], [1, 3, 1, 0x3], [3, 5, 1, 0x1a], [5, 6, 1, 0x3a], [7, 3, 5, 0x4], [39, 6, 2, 0x3b], [43, 4, 5, 0xb], [75, 4, 6, 0xc], [139, 5, 7, 0x1b], [267, 5, 8, 0x1c], [523, 6, 8, 0x3c], [779, 7, 9, 0x7d], [1291, 6, 11, 0x3d], [-32, 9, 32, 0x1fe, \"lower\"], [3339, 9, 32, 0x1ff], [2, 0x0]];\n      break;\n    case 10:\n      lines = [[-21, 7, 4, 0x7a], [-5, 8, 0, 0xfc], [-4, 7, 0, 0x7b], [-3, 5, 0, 0x18], [-2, 2, 2, 0x0], [2, 5, 0, 0x19], [3, 6, 0, 0x36], [4, 7, 0, 0x7c], [5, 8, 0, 0xfd], [6, 2, 6, 0x1], [70, 5, 5, 0x1a], [102, 6, 5, 0x37], [134, 6, 6, 0x38], [198, 6, 7, 0x39], [326, 6, 8, 0x3a], [582, 6, 9, 0x3b], [1094, 6, 10, 0x3c], [2118, 7, 11, 0x7d], [-22, 8, 32, 0xfe, \"lower\"], [4166, 8, 32, 0xff], [2, 0x2]];\n      break;\n    case 11:\n      lines = [[1, 1, 0, 0x0], [2, 2, 1, 0x2], [4, 4, 0, 0xc], [5, 4, 1, 0xd], [7, 5, 1, 0x1c], [9, 5, 2, 0x1d], [13, 6, 2, 0x3c], [17, 7, 2, 0x7a], [21, 7, 3, 0x7b], [29, 7, 4, 0x7c], [45, 7, 5, 0x7d], [77, 7, 6, 0x7e], [141, 7, 32, 0x7f]];\n      break;\n    case 12:\n      lines = [[1, 1, 0, 0x0], [2, 2, 0, 0x2], [3, 3, 1, 0x6], [5, 5, 0, 0x1c], [6, 5, 1, 0x1d], [8, 6, 1, 0x3c], [10, 7, 0, 0x7a], [11, 7, 1, 0x7b], [13, 7, 2, 0x7c], [17, 7, 3, 0x7d], [25, 7, 4, 0x7e], [41, 8, 5, 0xfe], [73, 8, 32, 0xff]];\n      break;\n    case 13:\n      lines = [[1, 1, 0, 0x0], [2, 3, 0, 0x4], [3, 4, 0, 0xc], [4, 5, 0, 0x1c], [5, 4, 1, 0xd], [7, 3, 3, 0x5], [15, 6, 1, 0x3a], [17, 6, 2, 0x3b], [21, 6, 3, 0x3c], [29, 6, 4, 0x3d], [45, 6, 5, 0x3e], [77, 7, 6, 0x7e], [141, 7, 32, 0x7f]];\n      break;\n    case 14:\n      lines = [[-2, 3, 0, 0x4], [-1, 3, 0, 0x5], [0, 1, 0, 0x0], [1, 3, 0, 0x6], [2, 3, 0, 0x7]];\n      break;\n    case 15:\n      lines = [[-24, 7, 4, 0x7c], [-8, 6, 2, 0x3c], [-4, 5, 1, 0x1c], [-2, 4, 0, 0xc], [-1, 3, 0, 0x4], [0, 1, 0, 0x0], [1, 3, 0, 0x5], [2, 4, 0, 0xd], [3, 5, 1, 0x1d], [5, 6, 2, 0x3d], [9, 7, 4, 0x7d], [-25, 7, 32, 0x7e, \"lower\"], [25, 7, 32, 0x7f]];\n      break;\n    default:\n      throw new Jbig2Error(`standard table B.${number} does not exist`);\n  }\n  for (let i = 0, ii = lines.length; i < ii; i++) {\n    lines[i] = new HuffmanLine(lines[i]);\n  }\n  table = new HuffmanTable(lines, true);\n  standardTablesCache[number] = table;\n  return table;\n}\nclass Reader {\n  constructor(data, start, end) {\n    this.data = data;\n    this.start = start;\n    this.end = end;\n    this.position = start;\n    this.shift = -1;\n    this.currentByte = 0;\n  }\n  readBit() {\n    if (this.shift < 0) {\n      if (this.position >= this.end) {\n        throw new Jbig2Error(\"end of data while reading bit\");\n      }\n      this.currentByte = this.data[this.position++];\n      this.shift = 7;\n    }\n    const bit = this.currentByte >> this.shift & 1;\n    this.shift--;\n    return bit;\n  }\n  readBits(numBits) {\n    let result = 0,\n      i;\n    for (i = numBits - 1; i >= 0; i--) {\n      result |= this.readBit() << i;\n    }\n    return result;\n  }\n  byteAlign() {\n    this.shift = -1;\n  }\n  next() {\n    if (this.position >= this.end) {\n      return -1;\n    }\n    return this.data[this.position++];\n  }\n}\nfunction getCustomHuffmanTable(index, referredTo, customTables) {\n  let currentIndex = 0;\n  for (let i = 0, ii = referredTo.length; i < ii; i++) {\n    const table = customTables[referredTo[i]];\n    if (table) {\n      if (index === currentIndex) {\n        return table;\n      }\n      currentIndex++;\n    }\n  }\n  throw new Jbig2Error(\"can't find custom Huffman table\");\n}\nfunction getTextRegionHuffmanTables(textRegion, referredTo, customTables, numberOfSymbols, reader) {\n  const codes = [];\n  for (let i = 0; i <= 34; i++) {\n    const codeLength = reader.readBits(4);\n    codes.push(new HuffmanLine([i, codeLength, 0, 0]));\n  }\n  const runCodesTable = new HuffmanTable(codes, false);\n  codes.length = 0;\n  for (let i = 0; i < numberOfSymbols;) {\n    const codeLength = runCodesTable.decode(reader);\n    if (codeLength >= 32) {\n      let repeatedLength, numberOfRepeats, j;\n      switch (codeLength) {\n        case 32:\n          if (i === 0) {\n            throw new Jbig2Error(\"no previous value in symbol ID table\");\n          }\n          numberOfRepeats = reader.readBits(2) + 3;\n          repeatedLength = codes[i - 1].prefixLength;\n          break;\n        case 33:\n          numberOfRepeats = reader.readBits(3) + 3;\n          repeatedLength = 0;\n          break;\n        case 34:\n          numberOfRepeats = reader.readBits(7) + 11;\n          repeatedLength = 0;\n          break;\n        default:\n          throw new Jbig2Error(\"invalid code length in symbol ID table\");\n      }\n      for (j = 0; j < numberOfRepeats; j++) {\n        codes.push(new HuffmanLine([i, repeatedLength, 0, 0]));\n        i++;\n      }\n    } else {\n      codes.push(new HuffmanLine([i, codeLength, 0, 0]));\n      i++;\n    }\n  }\n  reader.byteAlign();\n  const symbolIDTable = new HuffmanTable(codes, false);\n  let customIndex = 0,\n    tableFirstS,\n    tableDeltaS,\n    tableDeltaT;\n  switch (textRegion.huffmanFS) {\n    case 0:\n    case 1:\n      tableFirstS = getStandardTable(textRegion.huffmanFS + 6);\n      break;\n    case 3:\n      tableFirstS = getCustomHuffmanTable(customIndex, referredTo, customTables);\n      customIndex++;\n      break;\n    default:\n      throw new Jbig2Error(\"invalid Huffman FS selector\");\n  }\n  switch (textRegion.huffmanDS) {\n    case 0:\n    case 1:\n    case 2:\n      tableDeltaS = getStandardTable(textRegion.huffmanDS + 8);\n      break;\n    case 3:\n      tableDeltaS = getCustomHuffmanTable(customIndex, referredTo, customTables);\n      customIndex++;\n      break;\n    default:\n      throw new Jbig2Error(\"invalid Huffman DS selector\");\n  }\n  switch (textRegion.huffmanDT) {\n    case 0:\n    case 1:\n    case 2:\n      tableDeltaT = getStandardTable(textRegion.huffmanDT + 11);\n      break;\n    case 3:\n      tableDeltaT = getCustomHuffmanTable(customIndex, referredTo, customTables);\n      customIndex++;\n      break;\n    default:\n      throw new Jbig2Error(\"invalid Huffman DT selector\");\n  }\n  if (textRegion.refinement) {\n    throw new Jbig2Error(\"refinement with Huffman is not supported\");\n  }\n  return {\n    symbolIDTable,\n    tableFirstS,\n    tableDeltaS,\n    tableDeltaT\n  };\n}\nfunction getSymbolDictionaryHuffmanTables(dictionary, referredTo, customTables) {\n  let customIndex = 0,\n    tableDeltaHeight,\n    tableDeltaWidth;\n  switch (dictionary.huffmanDHSelector) {\n    case 0:\n    case 1:\n      tableDeltaHeight = getStandardTable(dictionary.huffmanDHSelector + 4);\n      break;\n    case 3:\n      tableDeltaHeight = getCustomHuffmanTable(customIndex, referredTo, customTables);\n      customIndex++;\n      break;\n    default:\n      throw new Jbig2Error(\"invalid Huffman DH selector\");\n  }\n  switch (dictionary.huffmanDWSelector) {\n    case 0:\n    case 1:\n      tableDeltaWidth = getStandardTable(dictionary.huffmanDWSelector + 2);\n      break;\n    case 3:\n      tableDeltaWidth = getCustomHuffmanTable(customIndex, referredTo, customTables);\n      customIndex++;\n      break;\n    default:\n      throw new Jbig2Error(\"invalid Huffman DW selector\");\n  }\n  let tableBitmapSize, tableAggregateInstances;\n  if (dictionary.bitmapSizeSelector) {\n    tableBitmapSize = getCustomHuffmanTable(customIndex, referredTo, customTables);\n    customIndex++;\n  } else {\n    tableBitmapSize = getStandardTable(1);\n  }\n  if (dictionary.aggregationInstancesSelector) {\n    tableAggregateInstances = getCustomHuffmanTable(customIndex, referredTo, customTables);\n  } else {\n    tableAggregateInstances = getStandardTable(1);\n  }\n  return {\n    tableDeltaHeight,\n    tableDeltaWidth,\n    tableBitmapSize,\n    tableAggregateInstances\n  };\n}\nfunction readUncompressedBitmap(reader, width, height) {\n  const bitmap = [];\n  for (let y = 0; y < height; y++) {\n    const row = new Uint8Array(width);\n    bitmap.push(row);\n    for (let x = 0; x < width; x++) {\n      row[x] = reader.readBit();\n    }\n    reader.byteAlign();\n  }\n  return bitmap;\n}\nfunction decodeMMRBitmap(input, width, height, endOfBlock) {\n  const params = {\n    K: -1,\n    Columns: width,\n    Rows: height,\n    BlackIs1: true,\n    EndOfBlock: endOfBlock\n  };\n  const decoder = new CCITTFaxDecoder(input, params);\n  const bitmap = [];\n  let currentByte,\n    eof = false;\n  for (let y = 0; y < height; y++) {\n    const row = new Uint8Array(width);\n    bitmap.push(row);\n    let shift = -1;\n    for (let x = 0; x < width; x++) {\n      if (shift < 0) {\n        currentByte = decoder.readNextChar();\n        if (currentByte === -1) {\n          currentByte = 0;\n          eof = true;\n        }\n        shift = 7;\n      }\n      row[x] = currentByte >> shift & 1;\n      shift--;\n    }\n  }\n  if (endOfBlock && !eof) {\n    const lookForEOFLimit = 5;\n    for (let i = 0; i < lookForEOFLimit; i++) {\n      if (decoder.readNextChar() === -1) {\n        break;\n      }\n    }\n  }\n  return bitmap;\n}\nclass Jbig2Image {\n  parseChunks(chunks) {\n    return parseJbig2Chunks(chunks);\n  }\n  parse(data) {\n    throw new Error(\"Not implemented: Jbig2Image.parse\");\n  }\n}\n\n;// ./src/core/jbig2_stream.js\n\n\n\n\n\nclass Jbig2Stream extends DecodeStream {\n  constructor(stream, maybeLength, params) {\n    super(maybeLength);\n    this.stream = stream;\n    this.dict = stream.dict;\n    this.maybeLength = maybeLength;\n    this.params = params;\n    this.isJbig2 = true;\n  }\n  get bytes() {\n    return shadow(this, \"bytes\", this.stream.getBytes(this.maybeLength));\n  }\n  ensureBuffer(requested) {}\n  readBlock() {\n    if (this.eof) {\n      return;\n    }\n    const jbig2Image = new Jbig2Image();\n    const chunks = [];\n    if (this.params instanceof Dict) {\n      const globalsStream = this.params.get(\"JBIG2Globals\");\n      if (globalsStream instanceof BaseStream) {\n        const globals = globalsStream.getBytes();\n        chunks.push({\n          data: globals,\n          start: 0,\n          end: globals.length\n        });\n      }\n    }\n    chunks.push({\n      data: this.bytes,\n      start: 0,\n      end: this.bytes.length\n    });\n    const data = jbig2Image.parseChunks(chunks);\n    const dataLength = data.length;\n    for (let i = 0; i < dataLength; i++) {\n      data[i] ^= 0xff;\n    }\n    this.buffer = data;\n    this.bufferLength = dataLength;\n    this.eof = true;\n  }\n}\n\n;// ./src/shared/image_utils.js\n\nfunction convertToRGBA(params) {\n  switch (params.kind) {\n    case ImageKind.GRAYSCALE_1BPP:\n      return convertBlackAndWhiteToRGBA(params);\n    case ImageKind.RGB_24BPP:\n      return convertRGBToRGBA(params);\n  }\n  return null;\n}\nfunction convertBlackAndWhiteToRGBA({\n  src,\n  srcPos = 0,\n  dest,\n  width,\n  height,\n  nonBlackColor = 0xffffffff,\n  inverseDecode = false\n}) {\n  const black = FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff;\n  const [zeroMapping, oneMapping] = inverseDecode ? [nonBlackColor, black] : [black, nonBlackColor];\n  const widthInSource = width >> 3;\n  const widthRemainder = width & 7;\n  const srcLength = src.length;\n  dest = new Uint32Array(dest.buffer);\n  let destPos = 0;\n  for (let i = 0; i < height; i++) {\n    for (const max = srcPos + widthInSource; srcPos < max; srcPos++) {\n      const elem = srcPos < srcLength ? src[srcPos] : 255;\n      dest[destPos++] = elem & 0b10000000 ? oneMapping : zeroMapping;\n      dest[destPos++] = elem & 0b1000000 ? oneMapping : zeroMapping;\n      dest[destPos++] = elem & 0b100000 ? oneMapping : zeroMapping;\n      dest[destPos++] = elem & 0b10000 ? oneMapping : zeroMapping;\n      dest[destPos++] = elem & 0b1000 ? oneMapping : zeroMapping;\n      dest[destPos++] = elem & 0b100 ? oneMapping : zeroMapping;\n      dest[destPos++] = elem & 0b10 ? oneMapping : zeroMapping;\n      dest[destPos++] = elem & 0b1 ? oneMapping : zeroMapping;\n    }\n    if (widthRemainder === 0) {\n      continue;\n    }\n    const elem = srcPos < srcLength ? src[srcPos++] : 255;\n    for (let j = 0; j < widthRemainder; j++) {\n      dest[destPos++] = elem & 1 << 7 - j ? oneMapping : zeroMapping;\n    }\n  }\n  return {\n    srcPos,\n    destPos\n  };\n}\nfunction convertRGBToRGBA({\n  src,\n  srcPos = 0,\n  dest,\n  destPos = 0,\n  width,\n  height\n}) {\n  let i = 0;\n  const len32 = src.length >> 2;\n  const src32 = new Uint32Array(src.buffer, srcPos, len32);\n  if (FeatureTest.isLittleEndian) {\n    for (; i < len32 - 2; i += 3, destPos += 4) {\n      const s1 = src32[i];\n      const s2 = src32[i + 1];\n      const s3 = src32[i + 2];\n      dest[destPos] = s1 | 0xff000000;\n      dest[destPos + 1] = s1 >>> 24 | s2 << 8 | 0xff000000;\n      dest[destPos + 2] = s2 >>> 16 | s3 << 16 | 0xff000000;\n      dest[destPos + 3] = s3 >>> 8 | 0xff000000;\n    }\n    for (let j = i * 4, jj = src.length; j < jj; j += 3) {\n      dest[destPos++] = src[j] | src[j + 1] << 8 | src[j + 2] << 16 | 0xff000000;\n    }\n  } else {\n    for (; i < len32 - 2; i += 3, destPos += 4) {\n      const s1 = src32[i];\n      const s2 = src32[i + 1];\n      const s3 = src32[i + 2];\n      dest[destPos] = s1 | 0xff;\n      dest[destPos + 1] = s1 << 24 | s2 >>> 8 | 0xff;\n      dest[destPos + 2] = s2 << 16 | s3 >>> 16 | 0xff;\n      dest[destPos + 3] = s3 << 8 | 0xff;\n    }\n    for (let j = i * 4, jj = src.length; j < jj; j += 3) {\n      dest[destPos++] = src[j] << 24 | src[j + 1] << 16 | src[j + 2] << 8 | 0xff;\n    }\n  }\n  return {\n    srcPos,\n    destPos\n  };\n}\nfunction grayToRGBA(src, dest) {\n  if (FeatureTest.isLittleEndian) {\n    for (let i = 0, ii = src.length; i < ii; i++) {\n      dest[i] = src[i] * 0x10101 | 0xff000000;\n    }\n  } else {\n    for (let i = 0, ii = src.length; i < ii; i++) {\n      dest[i] = src[i] * 0x1010100 | 0x000000ff;\n    }\n  }\n}\n\n;// ./src/core/jpg.js\n\n\n\nclass JpegError extends BaseException {\n  constructor(msg) {\n    super(msg, \"JpegError\");\n  }\n}\nclass DNLMarkerError extends BaseException {\n  constructor(message, scanLines) {\n    super(message, \"DNLMarkerError\");\n    this.scanLines = scanLines;\n  }\n}\nclass EOIMarkerError extends BaseException {\n  constructor(msg) {\n    super(msg, \"EOIMarkerError\");\n  }\n}\nconst dctZigZag = new Uint8Array([0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63]);\nconst dctCos1 = 4017;\nconst dctSin1 = 799;\nconst dctCos3 = 3406;\nconst dctSin3 = 2276;\nconst dctCos6 = 1567;\nconst dctSin6 = 3784;\nconst dctSqrt2 = 5793;\nconst dctSqrt1d2 = 2896;\nfunction buildHuffmanTable(codeLengths, values) {\n  let k = 0,\n    i,\n    j,\n    length = 16;\n  while (length > 0 && !codeLengths[length - 1]) {\n    length--;\n  }\n  const code = [{\n    children: [],\n    index: 0\n  }];\n  let p = code[0],\n    q;\n  for (i = 0; i < length; i++) {\n    for (j = 0; j < codeLengths[i]; j++) {\n      p = code.pop();\n      p.children[p.index] = values[k];\n      while (p.index > 0) {\n        p = code.pop();\n      }\n      p.index++;\n      code.push(p);\n      while (code.length <= i) {\n        code.push(q = {\n          children: [],\n          index: 0\n        });\n        p.children[p.index] = q.children;\n        p = q;\n      }\n      k++;\n    }\n    if (i + 1 < length) {\n      code.push(q = {\n        children: [],\n        index: 0\n      });\n      p.children[p.index] = q.children;\n      p = q;\n    }\n  }\n  return code[0].children;\n}\nfunction getBlockBufferOffset(component, row, col) {\n  return 64 * ((component.blocksPerLine + 1) * row + col);\n}\nfunction decodeScan(data, offset, frame, components, resetInterval, spectralStart, spectralEnd, successivePrev, successive, parseDNLMarker = false) {\n  const mcusPerLine = frame.mcusPerLine;\n  const progressive = frame.progressive;\n  const startOffset = offset;\n  let bitsData = 0,\n    bitsCount = 0;\n  function readBit() {\n    if (bitsCount > 0) {\n      bitsCount--;\n      return bitsData >> bitsCount & 1;\n    }\n    bitsData = data[offset++];\n    if (bitsData === 0xff) {\n      const nextByte = data[offset++];\n      if (nextByte) {\n        if (nextByte === 0xdc && parseDNLMarker) {\n          offset += 2;\n          const scanLines = readUint16(data, offset);\n          offset += 2;\n          if (scanLines > 0 && scanLines !== frame.scanLines) {\n            throw new DNLMarkerError(\"Found DNL marker (0xFFDC) while parsing scan data\", scanLines);\n          }\n        } else if (nextByte === 0xd9) {\n          if (parseDNLMarker) {\n            const maybeScanLines = blockRow * (frame.precision === 8 ? 8 : 0);\n            if (maybeScanLines > 0 && Math.round(frame.scanLines / maybeScanLines) >= 5) {\n              throw new DNLMarkerError(\"Found EOI marker (0xFFD9) while parsing scan data, \" + \"possibly caused by incorrect `scanLines` parameter\", maybeScanLines);\n            }\n          }\n          throw new EOIMarkerError(\"Found EOI marker (0xFFD9) while parsing scan data\");\n        }\n        throw new JpegError(`unexpected marker ${(bitsData << 8 | nextByte).toString(16)}`);\n      }\n    }\n    bitsCount = 7;\n    return bitsData >>> 7;\n  }\n  function decodeHuffman(tree) {\n    let node = tree;\n    while (true) {\n      node = node[readBit()];\n      switch (typeof node) {\n        case \"number\":\n          return node;\n        case \"object\":\n          continue;\n      }\n      throw new JpegError(\"invalid huffman sequence\");\n    }\n  }\n  function receive(length) {\n    let n = 0;\n    while (length > 0) {\n      n = n << 1 | readBit();\n      length--;\n    }\n    return n;\n  }\n  function receiveAndExtend(length) {\n    if (length === 1) {\n      return readBit() === 1 ? 1 : -1;\n    }\n    const n = receive(length);\n    if (n >= 1 << length - 1) {\n      return n;\n    }\n    return n + (-1 << length) + 1;\n  }\n  function decodeBaseline(component, blockOffset) {\n    const t = decodeHuffman(component.huffmanTableDC);\n    const diff = t === 0 ? 0 : receiveAndExtend(t);\n    component.blockData[blockOffset] = component.pred += diff;\n    let k = 1;\n    while (k < 64) {\n      const rs = decodeHuffman(component.huffmanTableAC);\n      const s = rs & 15,\n        r = rs >> 4;\n      if (s === 0) {\n        if (r < 15) {\n          break;\n        }\n        k += 16;\n        continue;\n      }\n      k += r;\n      const z = dctZigZag[k];\n      component.blockData[blockOffset + z] = receiveAndExtend(s);\n      k++;\n    }\n  }\n  function decodeDCFirst(component, blockOffset) {\n    const t = decodeHuffman(component.huffmanTableDC);\n    const diff = t === 0 ? 0 : receiveAndExtend(t) << successive;\n    component.blockData[blockOffset] = component.pred += diff;\n  }\n  function decodeDCSuccessive(component, blockOffset) {\n    component.blockData[blockOffset] |= readBit() << successive;\n  }\n  let eobrun = 0;\n  function decodeACFirst(component, blockOffset) {\n    if (eobrun > 0) {\n      eobrun--;\n      return;\n    }\n    let k = spectralStart;\n    const e = spectralEnd;\n    while (k <= e) {\n      const rs = decodeHuffman(component.huffmanTableAC);\n      const s = rs & 15,\n        r = rs >> 4;\n      if (s === 0) {\n        if (r < 15) {\n          eobrun = receive(r) + (1 << r) - 1;\n          break;\n        }\n        k += 16;\n        continue;\n      }\n      k += r;\n      const z = dctZigZag[k];\n      component.blockData[blockOffset + z] = receiveAndExtend(s) * (1 << successive);\n      k++;\n    }\n  }\n  let successiveACState = 0,\n    successiveACNextValue;\n  function decodeACSuccessive(component, blockOffset) {\n    let k = spectralStart;\n    const e = spectralEnd;\n    let r = 0;\n    let s;\n    let rs;\n    while (k <= e) {\n      const offsetZ = blockOffset + dctZigZag[k];\n      const sign = component.blockData[offsetZ] < 0 ? -1 : 1;\n      switch (successiveACState) {\n        case 0:\n          rs = decodeHuffman(component.huffmanTableAC);\n          s = rs & 15;\n          r = rs >> 4;\n          if (s === 0) {\n            if (r < 15) {\n              eobrun = receive(r) + (1 << r);\n              successiveACState = 4;\n            } else {\n              r = 16;\n              successiveACState = 1;\n            }\n          } else {\n            if (s !== 1) {\n              throw new JpegError(\"invalid ACn encoding\");\n            }\n            successiveACNextValue = receiveAndExtend(s);\n            successiveACState = r ? 2 : 3;\n          }\n          continue;\n        case 1:\n        case 2:\n          if (component.blockData[offsetZ]) {\n            component.blockData[offsetZ] += sign * (readBit() << successive);\n          } else {\n            r--;\n            if (r === 0) {\n              successiveACState = successiveACState === 2 ? 3 : 0;\n            }\n          }\n          break;\n        case 3:\n          if (component.blockData[offsetZ]) {\n            component.blockData[offsetZ] += sign * (readBit() << successive);\n          } else {\n            component.blockData[offsetZ] = successiveACNextValue << successive;\n            successiveACState = 0;\n          }\n          break;\n        case 4:\n          if (component.blockData[offsetZ]) {\n            component.blockData[offsetZ] += sign * (readBit() << successive);\n          }\n          break;\n      }\n      k++;\n    }\n    if (successiveACState === 4) {\n      eobrun--;\n      if (eobrun === 0) {\n        successiveACState = 0;\n      }\n    }\n  }\n  let blockRow = 0;\n  function decodeMcu(component, decode, mcu, row, col) {\n    const mcuRow = mcu / mcusPerLine | 0;\n    const mcuCol = mcu % mcusPerLine;\n    blockRow = mcuRow * component.v + row;\n    const blockCol = mcuCol * component.h + col;\n    const blockOffset = getBlockBufferOffset(component, blockRow, blockCol);\n    decode(component, blockOffset);\n  }\n  function decodeBlock(component, decode, mcu) {\n    blockRow = mcu / component.blocksPerLine | 0;\n    const blockCol = mcu % component.blocksPerLine;\n    const blockOffset = getBlockBufferOffset(component, blockRow, blockCol);\n    decode(component, blockOffset);\n  }\n  const componentsLength = components.length;\n  let component, i, j, k, n;\n  let decodeFn;\n  if (progressive) {\n    if (spectralStart === 0) {\n      decodeFn = successivePrev === 0 ? decodeDCFirst : decodeDCSuccessive;\n    } else {\n      decodeFn = successivePrev === 0 ? decodeACFirst : decodeACSuccessive;\n    }\n  } else {\n    decodeFn = decodeBaseline;\n  }\n  let mcu = 0,\n    fileMarker;\n  const mcuExpected = componentsLength === 1 ? components[0].blocksPerLine * components[0].blocksPerColumn : mcusPerLine * frame.mcusPerColumn;\n  let h, v;\n  while (mcu <= mcuExpected) {\n    const mcuToRead = resetInterval ? Math.min(mcuExpected - mcu, resetInterval) : mcuExpected;\n    if (mcuToRead > 0) {\n      for (i = 0; i < componentsLength; i++) {\n        components[i].pred = 0;\n      }\n      eobrun = 0;\n      if (componentsLength === 1) {\n        component = components[0];\n        for (n = 0; n < mcuToRead; n++) {\n          decodeBlock(component, decodeFn, mcu);\n          mcu++;\n        }\n      } else {\n        for (n = 0; n < mcuToRead; n++) {\n          for (i = 0; i < componentsLength; i++) {\n            component = components[i];\n            h = component.h;\n            v = component.v;\n            for (j = 0; j < v; j++) {\n              for (k = 0; k < h; k++) {\n                decodeMcu(component, decodeFn, mcu, j, k);\n              }\n            }\n          }\n          mcu++;\n        }\n      }\n    }\n    bitsCount = 0;\n    fileMarker = findNextFileMarker(data, offset);\n    if (!fileMarker) {\n      break;\n    }\n    if (fileMarker.invalid) {\n      const partialMsg = mcuToRead > 0 ? \"unexpected\" : \"excessive\";\n      warn(`decodeScan - ${partialMsg} MCU data, current marker is: ${fileMarker.invalid}`);\n      offset = fileMarker.offset;\n    }\n    if (fileMarker.marker >= 0xffd0 && fileMarker.marker <= 0xffd7) {\n      offset += 2;\n    } else {\n      break;\n    }\n  }\n  return offset - startOffset;\n}\nfunction quantizeAndInverse(component, blockBufferOffset, p) {\n  const qt = component.quantizationTable,\n    blockData = component.blockData;\n  let v0, v1, v2, v3, v4, v5, v6, v7;\n  let p0, p1, p2, p3, p4, p5, p6, p7;\n  let t;\n  if (!qt) {\n    throw new JpegError(\"missing required Quantization Table.\");\n  }\n  for (let row = 0; row < 64; row += 8) {\n    p0 = blockData[blockBufferOffset + row];\n    p1 = blockData[blockBufferOffset + row + 1];\n    p2 = blockData[blockBufferOffset + row + 2];\n    p3 = blockData[blockBufferOffset + row + 3];\n    p4 = blockData[blockBufferOffset + row + 4];\n    p5 = blockData[blockBufferOffset + row + 5];\n    p6 = blockData[blockBufferOffset + row + 6];\n    p7 = blockData[blockBufferOffset + row + 7];\n    p0 *= qt[row];\n    if ((p1 | p2 | p3 | p4 | p5 | p6 | p7) === 0) {\n      t = dctSqrt2 * p0 + 512 >> 10;\n      p[row] = t;\n      p[row + 1] = t;\n      p[row + 2] = t;\n      p[row + 3] = t;\n      p[row + 4] = t;\n      p[row + 5] = t;\n      p[row + 6] = t;\n      p[row + 7] = t;\n      continue;\n    }\n    p1 *= qt[row + 1];\n    p2 *= qt[row + 2];\n    p3 *= qt[row + 3];\n    p4 *= qt[row + 4];\n    p5 *= qt[row + 5];\n    p6 *= qt[row + 6];\n    p7 *= qt[row + 7];\n    v0 = dctSqrt2 * p0 + 128 >> 8;\n    v1 = dctSqrt2 * p4 + 128 >> 8;\n    v2 = p2;\n    v3 = p6;\n    v4 = dctSqrt1d2 * (p1 - p7) + 128 >> 8;\n    v7 = dctSqrt1d2 * (p1 + p7) + 128 >> 8;\n    v5 = p3 << 4;\n    v6 = p5 << 4;\n    v0 = v0 + v1 + 1 >> 1;\n    v1 = v0 - v1;\n    t = v2 * dctSin6 + v3 * dctCos6 + 128 >> 8;\n    v2 = v2 * dctCos6 - v3 * dctSin6 + 128 >> 8;\n    v3 = t;\n    v4 = v4 + v6 + 1 >> 1;\n    v6 = v4 - v6;\n    v7 = v7 + v5 + 1 >> 1;\n    v5 = v7 - v5;\n    v0 = v0 + v3 + 1 >> 1;\n    v3 = v0 - v3;\n    v1 = v1 + v2 + 1 >> 1;\n    v2 = v1 - v2;\n    t = v4 * dctSin3 + v7 * dctCos3 + 2048 >> 12;\n    v4 = v4 * dctCos3 - v7 * dctSin3 + 2048 >> 12;\n    v7 = t;\n    t = v5 * dctSin1 + v6 * dctCos1 + 2048 >> 12;\n    v5 = v5 * dctCos1 - v6 * dctSin1 + 2048 >> 12;\n    v6 = t;\n    p[row] = v0 + v7;\n    p[row + 7] = v0 - v7;\n    p[row + 1] = v1 + v6;\n    p[row + 6] = v1 - v6;\n    p[row + 2] = v2 + v5;\n    p[row + 5] = v2 - v5;\n    p[row + 3] = v3 + v4;\n    p[row + 4] = v3 - v4;\n  }\n  for (let col = 0; col < 8; ++col) {\n    p0 = p[col];\n    p1 = p[col + 8];\n    p2 = p[col + 16];\n    p3 = p[col + 24];\n    p4 = p[col + 32];\n    p5 = p[col + 40];\n    p6 = p[col + 48];\n    p7 = p[col + 56];\n    if ((p1 | p2 | p3 | p4 | p5 | p6 | p7) === 0) {\n      t = dctSqrt2 * p0 + 8192 >> 14;\n      if (t < -2040) {\n        t = 0;\n      } else if (t >= 2024) {\n        t = 255;\n      } else {\n        t = t + 2056 >> 4;\n      }\n      blockData[blockBufferOffset + col] = t;\n      blockData[blockBufferOffset + col + 8] = t;\n      blockData[blockBufferOffset + col + 16] = t;\n      blockData[blockBufferOffset + col + 24] = t;\n      blockData[blockBufferOffset + col + 32] = t;\n      blockData[blockBufferOffset + col + 40] = t;\n      blockData[blockBufferOffset + col + 48] = t;\n      blockData[blockBufferOffset + col + 56] = t;\n      continue;\n    }\n    v0 = dctSqrt2 * p0 + 2048 >> 12;\n    v1 = dctSqrt2 * p4 + 2048 >> 12;\n    v2 = p2;\n    v3 = p6;\n    v4 = dctSqrt1d2 * (p1 - p7) + 2048 >> 12;\n    v7 = dctSqrt1d2 * (p1 + p7) + 2048 >> 12;\n    v5 = p3;\n    v6 = p5;\n    v0 = (v0 + v1 + 1 >> 1) + 4112;\n    v1 = v0 - v1;\n    t = v2 * dctSin6 + v3 * dctCos6 + 2048 >> 12;\n    v2 = v2 * dctCos6 - v3 * dctSin6 + 2048 >> 12;\n    v3 = t;\n    v4 = v4 + v6 + 1 >> 1;\n    v6 = v4 - v6;\n    v7 = v7 + v5 + 1 >> 1;\n    v5 = v7 - v5;\n    v0 = v0 + v3 + 1 >> 1;\n    v3 = v0 - v3;\n    v1 = v1 + v2 + 1 >> 1;\n    v2 = v1 - v2;\n    t = v4 * dctSin3 + v7 * dctCos3 + 2048 >> 12;\n    v4 = v4 * dctCos3 - v7 * dctSin3 + 2048 >> 12;\n    v7 = t;\n    t = v5 * dctSin1 + v6 * dctCos1 + 2048 >> 12;\n    v5 = v5 * dctCos1 - v6 * dctSin1 + 2048 >> 12;\n    v6 = t;\n    p0 = v0 + v7;\n    p7 = v0 - v7;\n    p1 = v1 + v6;\n    p6 = v1 - v6;\n    p2 = v2 + v5;\n    p5 = v2 - v5;\n    p3 = v3 + v4;\n    p4 = v3 - v4;\n    if (p0 < 16) {\n      p0 = 0;\n    } else if (p0 >= 4080) {\n      p0 = 255;\n    } else {\n      p0 >>= 4;\n    }\n    if (p1 < 16) {\n      p1 = 0;\n    } else if (p1 >= 4080) {\n      p1 = 255;\n    } else {\n      p1 >>= 4;\n    }\n    if (p2 < 16) {\n      p2 = 0;\n    } else if (p2 >= 4080) {\n      p2 = 255;\n    } else {\n      p2 >>= 4;\n    }\n    if (p3 < 16) {\n      p3 = 0;\n    } else if (p3 >= 4080) {\n      p3 = 255;\n    } else {\n      p3 >>= 4;\n    }\n    if (p4 < 16) {\n      p4 = 0;\n    } else if (p4 >= 4080) {\n      p4 = 255;\n    } else {\n      p4 >>= 4;\n    }\n    if (p5 < 16) {\n      p5 = 0;\n    } else if (p5 >= 4080) {\n      p5 = 255;\n    } else {\n      p5 >>= 4;\n    }\n    if (p6 < 16) {\n      p6 = 0;\n    } else if (p6 >= 4080) {\n      p6 = 255;\n    } else {\n      p6 >>= 4;\n    }\n    if (p7 < 16) {\n      p7 = 0;\n    } else if (p7 >= 4080) {\n      p7 = 255;\n    } else {\n      p7 >>= 4;\n    }\n    blockData[blockBufferOffset + col] = p0;\n    blockData[blockBufferOffset + col + 8] = p1;\n    blockData[blockBufferOffset + col + 16] = p2;\n    blockData[blockBufferOffset + col + 24] = p3;\n    blockData[blockBufferOffset + col + 32] = p4;\n    blockData[blockBufferOffset + col + 40] = p5;\n    blockData[blockBufferOffset + col + 48] = p6;\n    blockData[blockBufferOffset + col + 56] = p7;\n  }\n}\nfunction buildComponentData(frame, component) {\n  const blocksPerLine = component.blocksPerLine;\n  const blocksPerColumn = component.blocksPerColumn;\n  const computationBuffer = new Int16Array(64);\n  for (let blockRow = 0; blockRow < blocksPerColumn; blockRow++) {\n    for (let blockCol = 0; blockCol < blocksPerLine; blockCol++) {\n      const offset = getBlockBufferOffset(component, blockRow, blockCol);\n      quantizeAndInverse(component, offset, computationBuffer);\n    }\n  }\n  return component.blockData;\n}\nfunction findNextFileMarker(data, currentPos, startPos = currentPos) {\n  const maxPos = data.length - 1;\n  let newPos = startPos < currentPos ? startPos : currentPos;\n  if (currentPos >= maxPos) {\n    return null;\n  }\n  const currentMarker = readUint16(data, currentPos);\n  if (currentMarker >= 0xffc0 && currentMarker <= 0xfffe) {\n    return {\n      invalid: null,\n      marker: currentMarker,\n      offset: currentPos\n    };\n  }\n  let newMarker = readUint16(data, newPos);\n  while (!(newMarker >= 0xffc0 && newMarker <= 0xfffe)) {\n    if (++newPos >= maxPos) {\n      return null;\n    }\n    newMarker = readUint16(data, newPos);\n  }\n  return {\n    invalid: currentMarker.toString(16),\n    marker: newMarker,\n    offset: newPos\n  };\n}\nclass JpegImage {\n  constructor({\n    decodeTransform = null,\n    colorTransform = -1\n  } = {}) {\n    this._decodeTransform = decodeTransform;\n    this._colorTransform = colorTransform;\n  }\n  parse(data, {\n    dnlScanLines = null\n  } = {}) {\n    function readDataBlock() {\n      const length = readUint16(data, offset);\n      offset += 2;\n      let endOffset = offset + length - 2;\n      const fileMarker = findNextFileMarker(data, endOffset, offset);\n      if (fileMarker?.invalid) {\n        warn(\"readDataBlock - incorrect length, current marker is: \" + fileMarker.invalid);\n        endOffset = fileMarker.offset;\n      }\n      const array = data.subarray(offset, endOffset);\n      offset += array.length;\n      return array;\n    }\n    function prepareComponents(frame) {\n      const mcusPerLine = Math.ceil(frame.samplesPerLine / 8 / frame.maxH);\n      const mcusPerColumn = Math.ceil(frame.scanLines / 8 / frame.maxV);\n      for (const component of frame.components) {\n        const blocksPerLine = Math.ceil(Math.ceil(frame.samplesPerLine / 8) * component.h / frame.maxH);\n        const blocksPerColumn = Math.ceil(Math.ceil(frame.scanLines / 8) * component.v / frame.maxV);\n        const blocksPerLineForMcu = mcusPerLine * component.h;\n        const blocksPerColumnForMcu = mcusPerColumn * component.v;\n        const blocksBufferSize = 64 * blocksPerColumnForMcu * (blocksPerLineForMcu + 1);\n        component.blockData = new Int16Array(blocksBufferSize);\n        component.blocksPerLine = blocksPerLine;\n        component.blocksPerColumn = blocksPerColumn;\n      }\n      frame.mcusPerLine = mcusPerLine;\n      frame.mcusPerColumn = mcusPerColumn;\n    }\n    let offset = 0;\n    let jfif = null;\n    let adobe = null;\n    let frame, resetInterval;\n    let numSOSMarkers = 0;\n    const quantizationTables = [];\n    const huffmanTablesAC = [],\n      huffmanTablesDC = [];\n    let fileMarker = readUint16(data, offset);\n    offset += 2;\n    if (fileMarker !== 0xffd8) {\n      throw new JpegError(\"SOI not found\");\n    }\n    fileMarker = readUint16(data, offset);\n    offset += 2;\n    markerLoop: while (fileMarker !== 0xffd9) {\n      let i, j, l;\n      switch (fileMarker) {\n        case 0xffe0:\n        case 0xffe1:\n        case 0xffe2:\n        case 0xffe3:\n        case 0xffe4:\n        case 0xffe5:\n        case 0xffe6:\n        case 0xffe7:\n        case 0xffe8:\n        case 0xffe9:\n        case 0xffea:\n        case 0xffeb:\n        case 0xffec:\n        case 0xffed:\n        case 0xffee:\n        case 0xffef:\n        case 0xfffe:\n          const appData = readDataBlock();\n          if (fileMarker === 0xffe0) {\n            if (appData[0] === 0x4a && appData[1] === 0x46 && appData[2] === 0x49 && appData[3] === 0x46 && appData[4] === 0) {\n              jfif = {\n                version: {\n                  major: appData[5],\n                  minor: appData[6]\n                },\n                densityUnits: appData[7],\n                xDensity: appData[8] << 8 | appData[9],\n                yDensity: appData[10] << 8 | appData[11],\n                thumbWidth: appData[12],\n                thumbHeight: appData[13],\n                thumbData: appData.subarray(14, 14 + 3 * appData[12] * appData[13])\n              };\n            }\n          }\n          if (fileMarker === 0xffee) {\n            if (appData[0] === 0x41 && appData[1] === 0x64 && appData[2] === 0x6f && appData[3] === 0x62 && appData[4] === 0x65) {\n              adobe = {\n                version: appData[5] << 8 | appData[6],\n                flags0: appData[7] << 8 | appData[8],\n                flags1: appData[9] << 8 | appData[10],\n                transformCode: appData[11]\n              };\n            }\n          }\n          break;\n        case 0xffdb:\n          const quantizationTablesLength = readUint16(data, offset);\n          offset += 2;\n          const quantizationTablesEnd = quantizationTablesLength + offset - 2;\n          let z;\n          while (offset < quantizationTablesEnd) {\n            const quantizationTableSpec = data[offset++];\n            const tableData = new Uint16Array(64);\n            if (quantizationTableSpec >> 4 === 0) {\n              for (j = 0; j < 64; j++) {\n                z = dctZigZag[j];\n                tableData[z] = data[offset++];\n              }\n            } else if (quantizationTableSpec >> 4 === 1) {\n              for (j = 0; j < 64; j++) {\n                z = dctZigZag[j];\n                tableData[z] = readUint16(data, offset);\n                offset += 2;\n              }\n            } else {\n              throw new JpegError(\"DQT - invalid table spec\");\n            }\n            quantizationTables[quantizationTableSpec & 15] = tableData;\n          }\n          break;\n        case 0xffc0:\n        case 0xffc1:\n        case 0xffc2:\n          if (frame) {\n            throw new JpegError(\"Only single frame JPEGs supported\");\n          }\n          offset += 2;\n          frame = {};\n          frame.extended = fileMarker === 0xffc1;\n          frame.progressive = fileMarker === 0xffc2;\n          frame.precision = data[offset++];\n          const sofScanLines = readUint16(data, offset);\n          offset += 2;\n          frame.scanLines = dnlScanLines || sofScanLines;\n          frame.samplesPerLine = readUint16(data, offset);\n          offset += 2;\n          frame.components = [];\n          frame.componentIds = {};\n          const componentsCount = data[offset++];\n          let maxH = 0,\n            maxV = 0;\n          for (i = 0; i < componentsCount; i++) {\n            const componentId = data[offset];\n            const h = data[offset + 1] >> 4;\n            const v = data[offset + 1] & 15;\n            if (maxH < h) {\n              maxH = h;\n            }\n            if (maxV < v) {\n              maxV = v;\n            }\n            const qId = data[offset + 2];\n            l = frame.components.push({\n              h,\n              v,\n              quantizationId: qId,\n              quantizationTable: null\n            });\n            frame.componentIds[componentId] = l - 1;\n            offset += 3;\n          }\n          frame.maxH = maxH;\n          frame.maxV = maxV;\n          prepareComponents(frame);\n          break;\n        case 0xffc4:\n          const huffmanLength = readUint16(data, offset);\n          offset += 2;\n          for (i = 2; i < huffmanLength;) {\n            const huffmanTableSpec = data[offset++];\n            const codeLengths = new Uint8Array(16);\n            let codeLengthSum = 0;\n            for (j = 0; j < 16; j++, offset++) {\n              codeLengthSum += codeLengths[j] = data[offset];\n            }\n            const huffmanValues = new Uint8Array(codeLengthSum);\n            for (j = 0; j < codeLengthSum; j++, offset++) {\n              huffmanValues[j] = data[offset];\n            }\n            i += 17 + codeLengthSum;\n            (huffmanTableSpec >> 4 === 0 ? huffmanTablesDC : huffmanTablesAC)[huffmanTableSpec & 15] = buildHuffmanTable(codeLengths, huffmanValues);\n          }\n          break;\n        case 0xffdd:\n          offset += 2;\n          resetInterval = readUint16(data, offset);\n          offset += 2;\n          break;\n        case 0xffda:\n          const parseDNLMarker = ++numSOSMarkers === 1 && !dnlScanLines;\n          offset += 2;\n          const selectorsCount = data[offset++],\n            components = [];\n          for (i = 0; i < selectorsCount; i++) {\n            const index = data[offset++];\n            const componentIndex = frame.componentIds[index];\n            const component = frame.components[componentIndex];\n            component.index = index;\n            const tableSpec = data[offset++];\n            component.huffmanTableDC = huffmanTablesDC[tableSpec >> 4];\n            component.huffmanTableAC = huffmanTablesAC[tableSpec & 15];\n            components.push(component);\n          }\n          const spectralStart = data[offset++],\n            spectralEnd = data[offset++],\n            successiveApproximation = data[offset++];\n          try {\n            const processed = decodeScan(data, offset, frame, components, resetInterval, spectralStart, spectralEnd, successiveApproximation >> 4, successiveApproximation & 15, parseDNLMarker);\n            offset += processed;\n          } catch (ex) {\n            if (ex instanceof DNLMarkerError) {\n              warn(`${ex.message} -- attempting to re-parse the JPEG image.`);\n              return this.parse(data, {\n                dnlScanLines: ex.scanLines\n              });\n            } else if (ex instanceof EOIMarkerError) {\n              warn(`${ex.message} -- ignoring the rest of the image data.`);\n              break markerLoop;\n            }\n            throw ex;\n          }\n          break;\n        case 0xffdc:\n          offset += 4;\n          break;\n        case 0xffff:\n          if (data[offset] !== 0xff) {\n            offset--;\n          }\n          break;\n        default:\n          const nextFileMarker = findNextFileMarker(data, offset - 2, offset - 3);\n          if (nextFileMarker?.invalid) {\n            warn(\"JpegImage.parse - unexpected data, current marker is: \" + nextFileMarker.invalid);\n            offset = nextFileMarker.offset;\n            break;\n          }\n          if (!nextFileMarker || offset >= data.length - 1) {\n            warn(\"JpegImage.parse - reached the end of the image data \" + \"without finding an EOI marker (0xFFD9).\");\n            break markerLoop;\n          }\n          throw new JpegError(\"JpegImage.parse - unknown marker: \" + fileMarker.toString(16));\n      }\n      fileMarker = readUint16(data, offset);\n      offset += 2;\n    }\n    if (!frame) {\n      throw new JpegError(\"JpegImage.parse - no frame data found.\");\n    }\n    this.width = frame.samplesPerLine;\n    this.height = frame.scanLines;\n    this.jfif = jfif;\n    this.adobe = adobe;\n    this.components = [];\n    for (const component of frame.components) {\n      const quantizationTable = quantizationTables[component.quantizationId];\n      if (quantizationTable) {\n        component.quantizationTable = quantizationTable;\n      }\n      this.components.push({\n        index: component.index,\n        output: buildComponentData(frame, component),\n        scaleX: component.h / frame.maxH,\n        scaleY: component.v / frame.maxV,\n        blocksPerLine: component.blocksPerLine,\n        blocksPerColumn: component.blocksPerColumn\n      });\n    }\n    this.numComponents = this.components.length;\n    return undefined;\n  }\n  _getLinearizedBlockData(width, height, isSourcePDF = false) {\n    const scaleX = this.width / width,\n      scaleY = this.height / height;\n    let component, componentScaleX, componentScaleY, blocksPerScanline;\n    let x, y, i, j, k;\n    let index;\n    let offset = 0;\n    let output;\n    const numComponents = this.components.length;\n    const dataLength = width * height * numComponents;\n    const data = new Uint8ClampedArray(dataLength);\n    const xScaleBlockOffset = new Uint32Array(width);\n    const mask3LSB = 0xfffffff8;\n    let lastComponentScaleX;\n    for (i = 0; i < numComponents; i++) {\n      component = this.components[i];\n      componentScaleX = component.scaleX * scaleX;\n      componentScaleY = component.scaleY * scaleY;\n      offset = i;\n      output = component.output;\n      blocksPerScanline = component.blocksPerLine + 1 << 3;\n      if (componentScaleX !== lastComponentScaleX) {\n        for (x = 0; x < width; x++) {\n          j = 0 | x * componentScaleX;\n          xScaleBlockOffset[x] = (j & mask3LSB) << 3 | j & 7;\n        }\n        lastComponentScaleX = componentScaleX;\n      }\n      for (y = 0; y < height; y++) {\n        j = 0 | y * componentScaleY;\n        index = blocksPerScanline * (j & mask3LSB) | (j & 7) << 3;\n        for (x = 0; x < width; x++) {\n          data[offset] = output[index + xScaleBlockOffset[x]];\n          offset += numComponents;\n        }\n      }\n    }\n    let transform = this._decodeTransform;\n    if (!isSourcePDF && numComponents === 4 && !transform) {\n      transform = new Int32Array([-256, 255, -256, 255, -256, 255, -256, 255]);\n    }\n    if (transform) {\n      for (i = 0; i < dataLength;) {\n        for (j = 0, k = 0; j < numComponents; j++, i++, k += 2) {\n          data[i] = (data[i] * transform[k] >> 8) + transform[k + 1];\n        }\n      }\n    }\n    return data;\n  }\n  get _isColorConversionNeeded() {\n    if (this.adobe) {\n      return !!this.adobe.transformCode;\n    }\n    if (this.numComponents === 3) {\n      if (this._colorTransform === 0) {\n        return false;\n      } else if (this.components[0].index === 0x52 && this.components[1].index === 0x47 && this.components[2].index === 0x42) {\n        return false;\n      }\n      return true;\n    }\n    if (this._colorTransform === 1) {\n      return true;\n    }\n    return false;\n  }\n  _convertYccToRgb(data) {\n    let Y, Cb, Cr;\n    for (let i = 0, length = data.length; i < length; i += 3) {\n      Y = data[i];\n      Cb = data[i + 1];\n      Cr = data[i + 2];\n      data[i] = Y - 179.456 + 1.402 * Cr;\n      data[i + 1] = Y + 135.459 - 0.344 * Cb - 0.714 * Cr;\n      data[i + 2] = Y - 226.816 + 1.772 * Cb;\n    }\n    return data;\n  }\n  _convertYccToRgba(data, out) {\n    for (let i = 0, j = 0, length = data.length; i < length; i += 3, j += 4) {\n      const Y = data[i];\n      const Cb = data[i + 1];\n      const Cr = data[i + 2];\n      out[j] = Y - 179.456 + 1.402 * Cr;\n      out[j + 1] = Y + 135.459 - 0.344 * Cb - 0.714 * Cr;\n      out[j + 2] = Y - 226.816 + 1.772 * Cb;\n      out[j + 3] = 255;\n    }\n    return out;\n  }\n  _convertYcckToRgb(data) {\n    let Y, Cb, Cr, k;\n    let offset = 0;\n    for (let i = 0, length = data.length; i < length; i += 4) {\n      Y = data[i];\n      Cb = data[i + 1];\n      Cr = data[i + 2];\n      k = data[i + 3];\n      data[offset++] = -122.67195406894 + Cb * (-6.60635669420364e-5 * Cb + 0.000437130475926232 * Cr - 5.4080610064599e-5 * Y + 0.00048449797120281 * k - 0.154362151871126) + Cr * (-0.000957964378445773 * Cr + 0.000817076911346625 * Y - 0.00477271405408747 * k + 1.53380253221734) + Y * (0.000961250184130688 * Y - 0.00266257332283933 * k + 0.48357088451265) + k * (-0.000336197177618394 * k + 0.484791561490776);\n      data[offset++] = 107.268039397724 + Cb * (2.19927104525741e-5 * Cb - 0.000640992018297945 * Cr + 0.000659397001245577 * Y + 0.000426105652938837 * k - 0.176491792462875) + Cr * (-0.000778269941513683 * Cr + 0.00130872261408275 * Y + 0.000770482631801132 * k - 0.151051492775562) + Y * (0.00126935368114843 * Y - 0.00265090189010898 * k + 0.25802910206845) + k * (-0.000318913117588328 * k - 0.213742400323665);\n      data[offset++] = -20.810012546947 + Cb * (-0.000570115196973677 * Cb - 2.63409051004589e-5 * Cr + 0.0020741088115012 * Y - 0.00288260236853442 * k + 0.814272968359295) + Cr * (-1.53496057440975e-5 * Cr - 0.000132689043961446 * Y + 0.000560833691242812 * k - 0.195152027534049) + Y * (0.00174418132927582 * Y - 0.00255243321439347 * k + 0.116935020465145) + k * (-0.000343531996510555 * k + 0.24165260232407);\n    }\n    return data.subarray(0, offset);\n  }\n  _convertYcckToRgba(data) {\n    for (let i = 0, length = data.length; i < length; i += 4) {\n      const Y = data[i];\n      const Cb = data[i + 1];\n      const Cr = data[i + 2];\n      const k = data[i + 3];\n      data[i] = -122.67195406894 + Cb * (-6.60635669420364e-5 * Cb + 0.000437130475926232 * Cr - 5.4080610064599e-5 * Y + 0.00048449797120281 * k - 0.154362151871126) + Cr * (-0.000957964378445773 * Cr + 0.000817076911346625 * Y - 0.00477271405408747 * k + 1.53380253221734) + Y * (0.000961250184130688 * Y - 0.00266257332283933 * k + 0.48357088451265) + k * (-0.000336197177618394 * k + 0.484791561490776);\n      data[i + 1] = 107.268039397724 + Cb * (2.19927104525741e-5 * Cb - 0.000640992018297945 * Cr + 0.000659397001245577 * Y + 0.000426105652938837 * k - 0.176491792462875) + Cr * (-0.000778269941513683 * Cr + 0.00130872261408275 * Y + 0.000770482631801132 * k - 0.151051492775562) + Y * (0.00126935368114843 * Y - 0.00265090189010898 * k + 0.25802910206845) + k * (-0.000318913117588328 * k - 0.213742400323665);\n      data[i + 2] = -20.810012546947 + Cb * (-0.000570115196973677 * Cb - 2.63409051004589e-5 * Cr + 0.0020741088115012 * Y - 0.00288260236853442 * k + 0.814272968359295) + Cr * (-1.53496057440975e-5 * Cr - 0.000132689043961446 * Y + 0.000560833691242812 * k - 0.195152027534049) + Y * (0.00174418132927582 * Y - 0.00255243321439347 * k + 0.116935020465145) + k * (-0.000343531996510555 * k + 0.24165260232407);\n      data[i + 3] = 255;\n    }\n    return data;\n  }\n  _convertYcckToCmyk(data) {\n    let Y, Cb, Cr;\n    for (let i = 0, length = data.length; i < length; i += 4) {\n      Y = data[i];\n      Cb = data[i + 1];\n      Cr = data[i + 2];\n      data[i] = 434.456 - Y - 1.402 * Cr;\n      data[i + 1] = 119.541 - Y + 0.344 * Cb + 0.714 * Cr;\n      data[i + 2] = 481.816 - Y - 1.772 * Cb;\n    }\n    return data;\n  }\n  _convertCmykToRgb(data) {\n    let c, m, y, k;\n    let offset = 0;\n    for (let i = 0, length = data.length; i < length; i += 4) {\n      c = data[i];\n      m = data[i + 1];\n      y = data[i + 2];\n      k = data[i + 3];\n      data[offset++] = 255 + c * (-0.00006747147073602441 * c + 0.0008379262121013727 * m + 0.0002894718188643294 * y + 0.003264231057537806 * k - 1.1185611867203937) + m * (0.000026374107616089405 * m - 0.00008626949158638572 * y - 0.0002748769067499491 * k - 0.02155688794978967) + y * (-0.00003878099212869363 * y - 0.0003267808279485286 * k + 0.0686742238595345) - k * (0.0003361971776183937 * k + 0.7430659151342254);\n      data[offset++] = 255 + c * (0.00013596372813588848 * c + 0.000924537132573585 * m + 0.00010567359618683593 * y + 0.0004791864687436512 * k - 0.3109689587515875) + m * (-0.00023545346108370344 * m + 0.0002702845253534714 * y + 0.0020200308977307156 * k - 0.7488052167015494) + y * (0.00006834815998235662 * y + 0.00015168452363460973 * k - 0.09751927774728933) - k * (0.0003189131175883281 * k + 0.7364883807733168);\n      data[offset++] = 255 + c * (0.000013598650411385307 * c + 0.00012423956175490851 * m + 0.0004751985097583589 * y - 0.0000036729317476630422 * k - 0.05562186980264034) + m * (0.00016141380598724676 * m + 0.0009692239130725186 * y + 0.0007782692450036253 * k - 0.44015232367526463) + y * (5.068882914068769e-7 * y + 0.0017778369011375071 * k - 0.7591454649749609) - k * (0.0003435319965105553 * k + 0.7063770186160144);\n    }\n    return data.subarray(0, offset);\n  }\n  _convertCmykToRgba(data) {\n    for (let i = 0, length = data.length; i < length; i += 4) {\n      const c = data[i];\n      const m = data[i + 1];\n      const y = data[i + 2];\n      const k = data[i + 3];\n      data[i] = 255 + c * (-0.00006747147073602441 * c + 0.0008379262121013727 * m + 0.0002894718188643294 * y + 0.003264231057537806 * k - 1.1185611867203937) + m * (0.000026374107616089405 * m - 0.00008626949158638572 * y - 0.0002748769067499491 * k - 0.02155688794978967) + y * (-0.00003878099212869363 * y - 0.0003267808279485286 * k + 0.0686742238595345) - k * (0.0003361971776183937 * k + 0.7430659151342254);\n      data[i + 1] = 255 + c * (0.00013596372813588848 * c + 0.000924537132573585 * m + 0.00010567359618683593 * y + 0.0004791864687436512 * k - 0.3109689587515875) + m * (-0.00023545346108370344 * m + 0.0002702845253534714 * y + 0.0020200308977307156 * k - 0.7488052167015494) + y * (0.00006834815998235662 * y + 0.00015168452363460973 * k - 0.09751927774728933) - k * (0.0003189131175883281 * k + 0.7364883807733168);\n      data[i + 2] = 255 + c * (0.000013598650411385307 * c + 0.00012423956175490851 * m + 0.0004751985097583589 * y - 0.0000036729317476630422 * k - 0.05562186980264034) + m * (0.00016141380598724676 * m + 0.0009692239130725186 * y + 0.0007782692450036253 * k - 0.44015232367526463) + y * (5.068882914068769e-7 * y + 0.0017778369011375071 * k - 0.7591454649749609) - k * (0.0003435319965105553 * k + 0.7063770186160144);\n      data[i + 3] = 255;\n    }\n    return data;\n  }\n  getData({\n    width,\n    height,\n    forceRGBA = false,\n    forceRGB = false,\n    isSourcePDF = false\n  }) {\n    if (this.numComponents > 4) {\n      throw new JpegError(\"Unsupported color mode\");\n    }\n    const data = this._getLinearizedBlockData(width, height, isSourcePDF);\n    if (this.numComponents === 1 && (forceRGBA || forceRGB)) {\n      const len = data.length * (forceRGBA ? 4 : 3);\n      const rgbaData = new Uint8ClampedArray(len);\n      let offset = 0;\n      if (forceRGBA) {\n        grayToRGBA(data, new Uint32Array(rgbaData.buffer));\n      } else {\n        for (const grayColor of data) {\n          rgbaData[offset++] = grayColor;\n          rgbaData[offset++] = grayColor;\n          rgbaData[offset++] = grayColor;\n        }\n      }\n      return rgbaData;\n    } else if (this.numComponents === 3 && this._isColorConversionNeeded) {\n      if (forceRGBA) {\n        const rgbaData = new Uint8ClampedArray(data.length / 3 * 4);\n        return this._convertYccToRgba(data, rgbaData);\n      }\n      return this._convertYccToRgb(data);\n    } else if (this.numComponents === 4) {\n      if (this._isColorConversionNeeded) {\n        if (forceRGBA) {\n          return this._convertYcckToRgba(data);\n        }\n        if (forceRGB) {\n          return this._convertYcckToRgb(data);\n        }\n        return this._convertYcckToCmyk(data);\n      } else if (forceRGBA) {\n        return this._convertCmykToRgba(data);\n      } else if (forceRGB) {\n        return this._convertCmykToRgb(data);\n      }\n    }\n    return data;\n  }\n}\n\n;// ./src/core/jpeg_stream.js\n\n\n\n\nclass JpegStream extends DecodeStream {\n  constructor(stream, maybeLength, params) {\n    let ch;\n    while ((ch = stream.getByte()) !== -1) {\n      if (ch === 0xff) {\n        stream.skip(-1);\n        break;\n      }\n    }\n    super(maybeLength);\n    this.stream = stream;\n    this.dict = stream.dict;\n    this.maybeLength = maybeLength;\n    this.params = params;\n  }\n  get bytes() {\n    return shadow(this, \"bytes\", this.stream.getBytes(this.maybeLength));\n  }\n  ensureBuffer(requested) {}\n  readBlock() {\n    if (this.eof) {\n      return;\n    }\n    const jpegOptions = {\n      decodeTransform: undefined,\n      colorTransform: undefined\n    };\n    const decodeArr = this.dict.getArray(\"D\", \"Decode\");\n    if ((this.forceRGBA || this.forceRGB) && Array.isArray(decodeArr)) {\n      const bitsPerComponent = this.dict.get(\"BPC\", \"BitsPerComponent\") || 8;\n      const decodeArrLength = decodeArr.length;\n      const transform = new Int32Array(decodeArrLength);\n      let transformNeeded = false;\n      const maxValue = (1 << bitsPerComponent) - 1;\n      for (let i = 0; i < decodeArrLength; i += 2) {\n        transform[i] = (decodeArr[i + 1] - decodeArr[i]) * 256 | 0;\n        transform[i + 1] = decodeArr[i] * maxValue | 0;\n        if (transform[i] !== 256 || transform[i + 1] !== 0) {\n          transformNeeded = true;\n        }\n      }\n      if (transformNeeded) {\n        jpegOptions.decodeTransform = transform;\n      }\n    }\n    if (this.params instanceof Dict) {\n      const colorTransform = this.params.get(\"ColorTransform\");\n      if (Number.isInteger(colorTransform)) {\n        jpegOptions.colorTransform = colorTransform;\n      }\n    }\n    const jpegImage = new JpegImage(jpegOptions);\n    jpegImage.parse(this.bytes);\n    const data = jpegImage.getData({\n      width: this.drawWidth,\n      height: this.drawHeight,\n      forceRGBA: this.forceRGBA,\n      forceRGB: this.forceRGB,\n      isSourcePDF: true\n    });\n    this.buffer = data;\n    this.bufferLength = data.length;\n    this.eof = true;\n  }\n}\n\n;// ./external/openjpeg/openjpeg.js\nvar OpenJPEG = (() => {\n  var _scriptDir = \"file:///Users/pmrowla/git/platform/llamaparse/pdf-js/external/openjpeg/openjpeg.js\";\n  return function (moduleArg = {}) {\n    var Module = moduleArg;\n    var readyPromiseResolve, readyPromiseReject;\n    var readyPromise = new Promise((resolve, reject) => {\n      readyPromiseResolve = resolve;\n      readyPromiseReject = reject;\n    });\n    \"use strict\";\n    Module.decode = function (bytes, ignoreColorSpace) {\n      const size = bytes.length;\n      const ptr = Module._malloc(size);\n      Module.HEAPU8.set(bytes, ptr);\n      const ret = Module._jp2_decode(ptr, size, ignoreColorSpace ? 1 : 0);\n      Module._free(ptr);\n      if (ret) {\n        const {\n          errorMessages: errorMessages\n        } = Module;\n        if (errorMessages) {\n          delete Module.errorMessages;\n          return errorMessages;\n        }\n        return \"Unknown error\";\n      }\n      const {\n        imageData: imageData\n      } = Module;\n      Module.imageData = null;\n      return imageData;\n    };\n    var moduleOverrides = Object.assign({}, Module);\n    var arguments_ = [];\n    var thisProgram = \"./this.program\";\n    var quit_ = (status, toThrow) => {\n      throw toThrow;\n    };\n    var ENVIRONMENT_IS_WEB = true;\n    var ENVIRONMENT_IS_WORKER = false;\n    var scriptDirectory = \"\";\n    var read_, readAsync, readBinary;\n    if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {\n      if (ENVIRONMENT_IS_WORKER) {\n        scriptDirectory = self.location.href;\n      } else if (typeof document != \"undefined\" && document.currentScript) {\n        scriptDirectory = document.currentScript.src;\n      }\n      if (_scriptDir) {\n        scriptDirectory = _scriptDir;\n      }\n      if (scriptDirectory.startsWith(\"blob:\")) {\n        scriptDirectory = \"\";\n      } else {\n        scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, \"\").lastIndexOf(\"/\") + 1);\n      }\n      read_ = url => {\n        var xhr = new XMLHttpRequest();\n        xhr.open(\"GET\", url, false);\n        xhr.send(null);\n        return xhr.responseText;\n      };\n      if (ENVIRONMENT_IS_WORKER) {\n        readBinary = url => {\n          var xhr = new XMLHttpRequest();\n          xhr.open(\"GET\", url, false);\n          xhr.responseType = \"arraybuffer\";\n          xhr.send(null);\n          return new Uint8Array(xhr.response);\n        };\n      }\n      readAsync = (url, onload, onerror) => {\n        var xhr = new XMLHttpRequest();\n        xhr.open(\"GET\", url, true);\n        xhr.responseType = \"arraybuffer\";\n        xhr.onload = () => {\n          if (xhr.status == 200 || xhr.status == 0 && xhr.response) {\n            onload(xhr.response);\n            return;\n          }\n          onerror();\n        };\n        xhr.onerror = onerror;\n        xhr.send(null);\n      };\n    } else {}\n    var out = Module[\"print\"] || console.log.bind(console);\n    var err = Module[\"printErr\"] || console.error.bind(console);\n    Object.assign(Module, moduleOverrides);\n    moduleOverrides = null;\n    if (Module[\"arguments\"]) arguments_ = Module[\"arguments\"];\n    if (Module[\"thisProgram\"]) thisProgram = Module[\"thisProgram\"];\n    if (Module[\"quit\"]) quit_ = Module[\"quit\"];\n    var wasmBinary;\n    if (Module[\"wasmBinary\"]) wasmBinary = Module[\"wasmBinary\"];\n    function intArrayFromBase64(s) {\n      var decoded = atob(s);\n      var bytes = new Uint8Array(decoded.length);\n      for (var i = 0; i < decoded.length; ++i) {\n        bytes[i] = decoded.charCodeAt(i);\n      }\n      return bytes;\n    }\n    function tryParseAsDataURI(filename) {\n      if (!isDataURI(filename)) {\n        return;\n      }\n      return intArrayFromBase64(filename.slice(dataURIPrefix.length));\n    }\n    var wasmMemory;\n    var ABORT = false;\n    var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;\n    function updateMemoryViews() {\n      var b = wasmMemory.buffer;\n      Module[\"HEAP8\"] = HEAP8 = new Int8Array(b);\n      Module[\"HEAP16\"] = HEAP16 = new Int16Array(b);\n      Module[\"HEAPU8\"] = HEAPU8 = new Uint8Array(b);\n      Module[\"HEAPU16\"] = HEAPU16 = new Uint16Array(b);\n      Module[\"HEAP32\"] = HEAP32 = new Int32Array(b);\n      Module[\"HEAPU32\"] = HEAPU32 = new Uint32Array(b);\n      Module[\"HEAPF32\"] = HEAPF32 = new Float32Array(b);\n      Module[\"HEAPF64\"] = HEAPF64 = new Float64Array(b);\n    }\n    var __ATPRERUN__ = [];\n    var __ATINIT__ = [];\n    var __ATPOSTRUN__ = [];\n    var runtimeInitialized = false;\n    function preRun() {\n      if (Module[\"preRun\"]) {\n        if (typeof Module[\"preRun\"] == \"function\") Module[\"preRun\"] = [Module[\"preRun\"]];\n        while (Module[\"preRun\"].length) {\n          addOnPreRun(Module[\"preRun\"].shift());\n        }\n      }\n      callRuntimeCallbacks(__ATPRERUN__);\n    }\n    function initRuntime() {\n      runtimeInitialized = true;\n      callRuntimeCallbacks(__ATINIT__);\n    }\n    function postRun() {\n      if (Module[\"postRun\"]) {\n        if (typeof Module[\"postRun\"] == \"function\") Module[\"postRun\"] = [Module[\"postRun\"]];\n        while (Module[\"postRun\"].length) {\n          addOnPostRun(Module[\"postRun\"].shift());\n        }\n      }\n      callRuntimeCallbacks(__ATPOSTRUN__);\n    }\n    function addOnPreRun(cb) {\n      __ATPRERUN__.unshift(cb);\n    }\n    function addOnInit(cb) {\n      __ATINIT__.unshift(cb);\n    }\n    function addOnPostRun(cb) {\n      __ATPOSTRUN__.unshift(cb);\n    }\n    var runDependencies = 0;\n    var runDependencyWatcher = null;\n    var dependenciesFulfilled = null;\n    function addRunDependency(id) {\n      runDependencies++;\n      Module[\"monitorRunDependencies\"]?.(runDependencies);\n    }\n    function removeRunDependency(id) {\n      runDependencies--;\n      Module[\"monitorRunDependencies\"]?.(runDependencies);\n      if (runDependencies == 0) {\n        if (runDependencyWatcher !== null) {\n          clearInterval(runDependencyWatcher);\n          runDependencyWatcher = null;\n        }\n        if (dependenciesFulfilled) {\n          var callback = dependenciesFulfilled;\n          dependenciesFulfilled = null;\n          callback();\n        }\n      }\n    }\n    var dataURIPrefix = \"data:application/octet-stream;base64,\";\n    var isDataURI = filename => filename.startsWith(dataURIPrefix);\n    var wasmBinaryFile;\n    wasmBinaryFile = \"data:application/octet-stream;base64,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AkAgFSAYIA1BAnRqQRBJckUEQANAIAEgAEECdCIEaiAEIAVq/QACAP0LAgAgAEEEaiIAIBNHDQALIBMiBCAIRg0BCyAEIQAgEQRAA0AgASAAIAJsQQJ0aiAFIABBAnRqKAIANgIAIABBAWohACAGQQFqIgYgEUcNAAsLIAQgCGtBfEsNAANAIAEgACACbEECdGogBSAAQQJ0aigCADYCACABIABBAWoiBCACbEECdGogBSAEQQJ0aigCADYCACABIABBAmoiBCACbEECdGogBSAEQQJ0aigCADYCACABIABBA2oiBCACbEECdGogBSAEQQJ0aigCADYCACAAQQRqIgAgCEcNAAsLIAFBBGohASANQQFqIg0gA0cNAAsMAQsCQAJAAkAgCEEBaw4CAAECCyADQQBMDQJBACECAkAgA0EESQRAIAEhAAwBCyABIANB/P///wdxIgJBAnRqIQADQCABIAZBAnRqIgQgBP0AAgAiIf0bAEECbf0RICH9GwFBAm39HAEgIf0bAkECbf0cAiAh/RsDQQJt/RwD/QsCACAGQQRqIgYgAkcNAAsgAiADRg0DCwNAIAAgACgCAEECbTYCACAAQQRqIQAgAkEBaiICIANHDQALDAILIANBAEwNASAAKAIAIQkgAiAKbEECdCEHA0AgCSABKAIAIAEgB2oiBCgCAEEBakEBdWsiADYCBCAJIAAgBCgCAGoiADYCACABIAA2AgAgASACQQJ0aiAJKAIENgIAIAFBBGohASAGQQFqIgYgA0cNAAsMAQsgCEEDSA0AIANBAEwNACAAKAIAIgUgCCAIQQFxIhRFIgZrQQRrIglBAXYiC0ECdCIHIAEgA0ECdCIAampJIAUgC0EDdGpBDGoiBCABQQRqS3EgBUEEaiAAIAEgCkECdGoiAGogB2pBCGpJIABBCGogBElxciEVIAJBAUcgCEEESXIhFiACQQFGIAlBBUtxIRcgCEH8////B3EhECAIQQNxIREgASAFayEYIAUgCEECdGpBBGshGSAFIAhBAmsiAEECdGohGiALQQFqIhJBfHEiDEEBciETIAxBAXRBAXIhCyACIApsQQJ0IRsgACAGa0ECSSEcIAhBAXZBAWsgAmxBAnQhHQNAIAUgASgCACABIBtqIg8gAkECdGooAgAiCSAPKAIAIgBqQQJqQQJ1ayIHIABqNgIA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aCk9AAkJCSBzdGVwc2l6ZXMgKG0sZSk9AC4AKG51bGwpACglZCwlZCkgACVzfQoACQkgfQoAW0RFVl0gRHVtcCBhbiBpbWFnZV9jb21wX2hlYWRlciBzdHJ1Y3QgewoAW0RFVl0gRHVtcCBhbiBpbWFnZV9oZWFkZXIgc3RydWN0IHsKAEltYWdlIGluZm8gewoACSBkZWZhdWx0IHRpbGUgewoAJXMJIGNvbXBvbmVudCAlZCB7CgAJCSBjb21wICVkIHsKAAkgVGlsZSBpbmRleDogewoACSBNYXJrZXIgbGlzdDogewoAQ29kZXN0cmVhbSBpbmRleCBmcm9tIG1haW4gaGVhZGVyOiB7CgBDb2Rlc3RyZWFtIGluZm8gZnJvbSBtYWluIGhlYWRlcjogewoAU3RyZWFtIGVycm9yIHdoaWxlIHJlYWRpbmcgSlAyIEhlYWRlciBib3gKAEZvdW5kIGEgbWlzcGxhY2VkICclYyVjJWMlYycgYm94IG91dHNpZGUganAyaCBib3gKAE1hbGZvcm1lZCBKUDIgZmlsZSBmb3JtYXQ6IGZpcnN0IGJveCBtdXN0IGJlIEpQRUcgMjAwMCBzaWduYXR1cmUgYm94CgBNYWxmb3JtZWQgSlAyIGZpbGUgZm9ybWF0OiBzZWNvbmQgYm94IG11c3QgYmUgZmlsZSB0eXBlIGJveAoATm90IGVub3VnaCBtZW1vcnkgdG8gaGFuZGxlIGpwZWcyMDAwIGJveAoATm90IGVub3VnaCBtZW1vcnkgd2l0aCBGVFlQIEJveAoAQSBtYXJrZXIgSUQgd2FzIGV4cGVjdGVkICgweGZmLS0pIGluc3RlYWQgb2YgJS44eAoACQkgbWN0PSV4CgAJCQkgY2Jsa3N0eT0lI3gKAAkJCSBjc3R5PSUjeAoACQkgcHJnPSUjeAoASW50ZWdlciBvdmVyZmxvdwoACSB0ZHg9JXUsIHRkeT0ldQoACSB0dz0ldSwgdGg9JXUKAAkgdHgwPSV1LCB0eTA9JXUKAEludmFsaWQgY29tcG9uZW50IGluZGV4OiAldQoAU3RyZWFtIHRvbyBzaG9ydAoATWFya2VyIGhhbmRsZXIgZnVuY3Rpb24gZmFpbGVkIHRvIHJlYWQgdGhlIG1hcmtlciBzZWdtZW50CgBOb3QgZW5vdWdoIG1lbW9yeSBmb3IgY3VycmVudCBwcmVjaW5jdCBjb2RlYmxvY2sgZWxlbWVudAoARXJyb3IgcmVhZGluZyBTUENvZCBTUENvYyBlbGVtZW50CgBFcnJvciByZWFkaW5nIFNRY2Qgb3IgU1FjYyBlbGVtZW50CgBBIEJQQ0MgaGVhZGVyIGJveCBpcyBhdmFpbGFibGUgYWx0aG91Z2ggQlBDIGdpdmVuIGJ5IHRoZSBJSERSIGJveCAoJWQpIGluZGljYXRlIGNvbXBvbmVudHMgYml0IGRlcHRoIGlzIGNvbnN0YW50CgBFcnJvciB3aXRoIFNJWiBtYXJrZXI6IGlsbGVnYWwgdGlsZSBvZmZzZXQKAEludmFsaWQgcHJlY2luY3QKAE5vdCBlbm91Z2ggbWVtb3J5IHRvIGhhbmRsZSBiYW5kIHByZWNpbnRzCgBGYWlsZWQgdG8gZGVjb2RlIGFsbCB1c2VkIGNvbXBvbmVudHMKAFNpemUgb2YgY29kZSBibG9jayBkYXRhIGV4Y2VlZHMgc3lzdGVtIGxpbWl0cwoAU2l6ZSBvZiB0aWxlIGRhdGEgZXhjZWVkcyBzeXN0ZW0gbGltaXRzCgBDYW5ub3QgdGFrZSBpbiBjaGFyZ2UgbXVsdGlwbGUgTUNUIG1hcmtlcnMKAENvcnJ1cHRlZCBQUE0gbWFya2VycwoATm90IGVub3VnaCBtZW1vcnkgZm9yIHRpbGUgcmVzb2x1dGlvbnMKAENhbm5vdCB0YWtlIGluIGNoYXJnZSBtdWx0aXBsZSBjb2xsZWN0aW9ucwoASW52YWxpZCBQQ0xSIGJveC4gUmVwb3J0cyAwIHBhbGV0dGUgY29sdW1ucwoAV2UgZG8gbm90IHN1cHBvcnQgUk9JIGluIGRlY29kaW5nIEhUIGNvZGVibG9ja3MKAENhbm5vdCBoYW5kbGUgYm94IG9mIHVuZGVmaW5lZCBzaXplcwoAQ2Fubm90IHRha2UgaW4gY2hhcmdlIGNvbGxlY3Rpb25zIHdpdGhvdXQgc2FtZSBudW1iZXIgb2YgaW5kaXhlcwoASW52YWxpZCB0aWxlYy0+d2luX3h4eCB2YWx1ZXMKAENhbm5vdCBoYW5kbGUgYm94IG9mIGxlc3MgdGhhbiA4IGJ5dGVzCgBDYW5ub3QgaGFuZGxlIFhMIGJveCBvZiBsZXNzIHRoYW4gMTYgYnl0ZXMKAENvbXBvbmVudCBpbmRleCAldSB1c2VkIHNldmVyYWwgdGltZXMKAEludmFsaWQgUENMUiBib3guIFJlcG9ydHMgJWQgZW50cmllcwoATm90IGVub3VnaCBtZW1vcnkgdG8gY3JlYXRlIFRhZy10cmVlIG5vZGVzCgBDYW5ub3QgdGFrZSBpbiBjaGFyZ2UgbWN0IGRhdGEgd2l0aGluIG11bHRpcGxlIE1DVCByZWNvcmRzCgBDYW5ub3QgZGVjb2RlIHRpbGUsIG1lbW9yeSBlcnJvcgoAb3BqX2oya19hcHBseV9uYl90aWxlX3BhcnRzX2NvcnJlY3Rpb24gZXJyb3IKAFByb2JsZW0gd2l0aCBza2lwcGluZyBKUEVHMjAwMCBib3gsIHN0cmVhbSBlcnJvcgoAUHJvYmxlbSB3aXRoIHJlYWRpbmcgSlBFRzIwMDAgYm94LCBzdHJlYW0gZXJyb3IKAFVua25vd24gbWFya2VyCgBOb3QgZW5vdWdoIG1lbW9yeSB0byBhZGQgdGwgbWFya2VyCgBOb3QgZW5vdWdoIG1lbW9yeSB0byBhZGQgbWggbWFya2VyCgBOb3QgZW5vdWdoIG1lbW9yeSB0byB0YWtlIGluIGNoYXJnZSBTSVogbWFya2VyCgBFcnJvciByZWFkaW5nIFBQVCBtYXJrZXIKAE5vdCBlbm91Z2ggbWVtb3J5IHRvIHJlYWQgUFBUIG1hcmtlcgoARXJyb3IgcmVhZGluZyBTT1QgbWFya2VyCgBFcnJvciByZWFkaW5nIFBMVCBtYXJrZXIKAEVycm9yIHJlYWRpbmcgTUNUIG1hcmtlcgoATm90IGVub3VnaCBtZW1vcnkgdG8gcmVhZCBNQ1QgbWFya2VyCgBOb3QgZW5vdWdoIHNwYWNlIGZvciBleHBlY3RlZCBTT1AgbWFya2VyCgBFeHBlY3RlZCBTT1AgbWFya2VyCgBFcnJvciByZWFkaW5nIE1DTyBtYXJrZXIKAEVycm9yIHJlYWRpbmcgUkdOIG1hcmtlcgoARXJyb3IgcmVhZGluZyBQUE0gbWFya2VyCgBOb3QgZW5vdWdoIG1lbW9yeSB0byByZWFkIFBQTSBtYXJrZXIKAEVycm9yIHJlYWRpbmcgVExNIG1hcmtlcgoARXJyb3IgcmVhZGluZyBQTE0gbWFya2VyCgBOb3QgZW5vdWdoIHNwYWNlIGZvciBleHBlY3RlZCBFUEggbWFya2VyCgBFeHBlY3RlZCBFUEggbWFya2VyCgBFcnJvciByZWFkaW5nIENSRyBtYXJrZXIKAFVua25vd24gcHJvZ3Jlc3Npb24gb3JkZXIgaW4gQ09EIG1hcmtlcgoAVW5rbm93biBTY29kIHZhbHVlIGluIENPRCBtYXJrZXIKAEVycm9yIHJlYWRpbmcgQ09EIG1hcmtlcgoARXJyb3IgcmVhZGluZyBRQ0QgbWFya2VyCgBDcnJvciByZWFkaW5nIENCRCBtYXJrZXIKAEVycm9yIHJlYWRpbmcgUE9DIG1hcmtlcgoARXJyb3IgcmVhZGluZyBDT0MgbWFya2VyCgBFcnJvciByZWFkaW5nIFFDQyBtYXJrZXIKAEVycm9yIHJlYWRpbmcgTUNDIG1hcmtlcgoATm90IGVub3VnaCBtZW1vcnkgdG8gcmVhZCBNQ0MgbWFya2VyCgByZXF1aXJlZCBTSVogbWFya2VyIG5vdCBmb3VuZCBpbiBtYWluIGhlYWRlcgoAcmVxdWlyZWQgQ09EIG1hcmtlciBub3QgZm91bmQgaW4gbWFpbiBoZWFkZXIKAHJlcXVpcmVkIFFDRCBtYXJrZXIgbm90IGZvdW5kIGluIG1haW4gaGVhZGVyCgBOb3QgZW5vdWdoIG1lbW9yeSB0byBoYW5kbGUganBlZzIwMDAgZmlsZSBoZWFkZXIKAE5vdCBlbm91Z2ggbWVtb3J5IHRvIHJlYWQgaGVhZGVyCgBFcnJvciB3aXRoIEpQIFNpZ25hdHVyZSA6IGJhZCBtYWdpYyBudW1iZXIKAEluIFNPVCBtYXJrZXIsIFRQU290ICglZCkgaXMgbm90IHZhbGlkIHJlZ2FyZHMgdG8gdGhlIGN1cnJlbnQgbnVtYmVyIG9mIHRpbGUtcGFydCAoJWQpLCBnaXZpbmcgdXAKAEluIFNPVCBtYXJrZXIsIFRQU290ICglZCkgaXMgbm90IHZhbGlkIHJlZ2FyZHMgdG8gdGhlIHByZXZpb3VzIG51bWJlciBvZiB0aWxlLXBhcnQgKCVkKSwgZ2l2aW5nIHVwCgBJbiBTT1QgbWFya2VyLCBUUFNvdCAoJWQpIGlzIG5vdCB2YWxpZCByZWdhcmRzIHRvIHRoZSBjdXJyZW50IG51bWJlciBvZiB0aWxlLXBhcnQgKGhlYWRlcikgKCVkKSwgZ2l2aW5nIHVwCgB0aWxlcyByZXF1aXJlIGF0IGxlYXN0IG9uZSByZXNvbHV0aW9uCgBNYXJrZXIgaXMgbm90IGNvbXBsaWFudCB3aXRoIGl0cyBwb3NpdGlvbgoAUHJvYmxlbSB3aXRoIHNlZWsgZnVuY3Rpb24KAEVycm9yIHJlYWRpbmcgU1BDb2QgU1BDb2MgZWxlbWVudCwgSW52YWxpZCBjYmxrdy9jYmxraCBjb21iaW5hdGlvbgoASW52YWxpZCBtdWx0aXBsZSBjb21wb25lbnQgdHJhbnNmb3JtYXRpb24KAENhbm5vdCB0YWtlIGluIGNoYXJnZSBjb2xsZWN0aW9ucyBvdGhlciB0aGFuIGFycmF5IGRlY29ycmVsYXRpb24KAFRvbyBsYXJnZSB2YWx1ZSBmb3IgTnBwbQoATm90IGVub3VnaCBieXRlcyB0byByZWFkIE5wcG0KAGJhZCBwbGFjZWQganBlZyBjb2Rlc3RyZWFtCgAJIE1haW4gaGVhZGVyIHN0YXJ0IHBvc2l0aW9uPSVsbGkKCSBNYWluIGhlYWRlciBlbmQgcG9zaXRpb249JWxsaQoATWFya2VyIHNpemUgaW5jb25zaXN0ZW50IHdpdGggc3RyZWFtIGxlbmd0aAoAVGlsZSBwYXJ0IGxlbmd0aCBzaXplIGluY29uc2lzdGVudCB3aXRoIHN0cmVhbSBsZW5ndGgKAENhbm5vdCB0YWtlIGluIGNoYXJnZSBtdWx0aXBsZSBkYXRhIHNwYW5uaW5nCgBXcm9uZyBmbGFnCgBFcnJvciB3aXRoIEZUWVAgc2lnbmF0dXJlIEJveCBzaXplCgBFcnJvciB3aXRoIEpQIHNpZ25hdHVyZSBCb3ggc2l6ZQoASW52YWxpZCBwcmVjaW5jdCBzaXplCgBJbmNvbnNpc3RlbnQgbWFya2VyIHNpemUKAEludmFsaWQgbWFya2VyIHNpemUKAEVycm9yIHdpdGggU0laIG1hcmtlciBzaXplCgBOb3QgZW5vdWdoIG1lbW9yeSB0byBhZGQgYSBuZXcgdmFsaWRhdGlvbiBwcm9jZWR1cmUKAE5vdCBlbm91Z2ggbWVtb3J5IHRvIGRlY29kZSB0aWxlCgBGYWlsZWQgdG8gZGVjb2RlIHRoZSBjb2Rlc3RyZWFtIGluIHRoZSBKUDIgZmlsZQoAQ2Fubm90IHRha2UgaW4gY2hhcmdlIGNvbGxlY3Rpb25zIHdpdGggaW5kaXggc2h1ZmZsZQoAQ2Fubm90IGFsbG9jYXRlIFRpZXIgMSBoYW5kbGUKAE5vIGRlY29kZWQgYXJlYSBwYXJhbWV0ZXJzLCBzZXQgdGhlIGRlY29kZWQgYXJlYSB0byB0aGUgd2hvbGUgaW1hZ2UKAE5vdCBlbm91Z2ggbWVtb3J5IHRvIGNyZWF0ZSBUYWctdHJlZQoATm90IGVub3VnaCBtZW1vcnkgdG8gcmVpbml0aWFsaXplIHRoZSB0YWcgdHJlZQoARXJyb3IgcmVhZGluZyBTUENvZCBTUENvYyBlbGVtZW50LCBJbnZhbGlkIHRyYW5zZm9ybWF0aW9uIGZvdW5kCgBFcnJvciByZWFkaW5nIFNQQ29kIFNQQ29jIGVsZW1lbnQuIFVuc3VwcG9ydGVkIE1peGVkIEhUIGNvZGUtYmxvY2sgc3R5bGUgZm91bmQKAFRpbGUgWSBjb29yZGluYXRlcyBhcmUgbm90IHN1cHBvcnRlZAoAVGlsZSBYIGNvb3JkaW5hdGVzIGFyZSBub3Qgc3VwcG9ydGVkCgBJbWFnZSBjb29yZGluYXRlcyBhYm92ZSBJTlRfTUFYIGFyZSBub3Qgc3VwcG9ydGVkCgBKUEVHMjAwMCBIZWFkZXIgYm94IG5vdCByZWFkIHlldCwgJyVjJWMlYyVjJyBib3ggd2lsbCBiZSBpZ25vcmVkCgBvcGpfajJrX21lcmdlX3BwdCgpIGhhcyBhbHJlYWR5IGJlZW4gY2FsbGVkCgBOb3QgZW5vdWdoIG1lbW9yeSB0byByZWFkIFNPVCBtYXJrZXIuIFRpbGUgaW5kZXggYWxsb2NhdGlvbiBmYWlsZWQKAElnbm9yaW5nIGloZHIgYm94LiBGaXJzdCBpaGRyIGJveCBhbHJlYWR5IHJlYWQKAFpwcHQgJXUgYWxyZWFkeSByZWFkCgBacHBtICV1IGFscmVhZHkgcmVhZAoAUFRFUk0gY2hlY2sgZmFpbHVyZTogJWQgc3ludGhldGl6ZWQgMHhGRiBtYXJrZXJzIHJlYWQKAAkJCSBjYmxrdz0yXiVkCgAJCQkgY2Jsa2g9Ml4lZAoACQkJIHFudHN0eT0lZAoAJXMgZHg9JWQsIGR5PSVkCgAJCQkgcm9pc2hpZnQ9JWQKAAkJCSBudW1nYml0cz0lZAoACQkgbnVtbGF5ZXJzPSVkCgAlcyBudW1jb21wcz0lZAoAb3BqX2pwMl9hcHBseV9jZGVmOiBhY249JWQsIG51bWNvbXBzPSVkCgBvcGpfanAyX2FwcGx5X2NkZWY6IGNuPSVkLCBudW1jb21wcz0lZAoACQkJIG51bXJlc29sdXRpb25zPSVkCgAJCSB0eXBlPSUjeCwgcG9zPSVsbGksIGxlbj0lZAoAJXMgc2duZD0lZAoACQkJIHFtZmJpZD0lZAoAJXMgcHJlYz0lZAoACQkgbmIgb2YgdGlsZS1wYXJ0IGluIHRpbGUgWyVkXT0lZAoAJXMgeDE9JWQsIHkxPSVkCgAlcyB4MD0lZCwgeTA9JWQKAEZhaWxlZCB0byBkZWNvZGUgdGlsZSAlZC8lZAoAU2V0dGluZyBkZWNvZGluZyBhcmVhIHRvICVkLCVkLCVkLCVkCgBGYWlsZWQgdG8gZGVjb2RlIGNvbXBvbmVudCAlZAoASW52YWxpZCB2YWx1ZSBmb3IgbnVtcmVzb2x1dGlvbnMgOiAlZCwgbWF4IHZhbHVlIGlzIHNldCBpbiBvcGVuanBlZy5oIGF0ICVkCgBJbnZhbGlkIGNvbXBvbmVudCBudW1iZXI6ICVkLCByZWdhcmRpbmcgdGhlIG51bWJlciBvZiBjb21wb25lbnRzICVkCgBUb28gbWFueSBQT0NzICVkCgBJbnZhbGlkIHRpbGUgbnVtYmVyICVkCgBJbnZhbGlkIHRpbGUgcGFydCBpbmRleCBmb3IgdGlsZSBudW1iZXIgJWQuIEdvdCAlZCwgZXhwZWN0ZWQgJWQKAEVycm9yIHdpdGggU0laIG1hcmtlcjogbnVtYmVyIG9mIGNvbXBvbmVudCBpcyBpbGxlZ2FsIC0+ICVkCgBOb3QgZW5vdWdoIG1lbW9yeSBmb3IgY2llbGFiCgBDYW5ub3QgYWxsb2NhdGUgY2Jsay0+ZGVjb2RlZF9kYXRhCgBGYWlsZWQgdG8gbWVyZ2UgUFBUIGRhdGEKAEZhaWxlZCB0byBtZXJnZSBQUE0gZGF0YQoASW52YWxpZCBudW1iZXIgb2YgbGF5ZXJzIGluIENPRCBtYXJrZXIgOiAlZCBub3QgaW4gcmFuZ2UgWzEtNjU1MzVdCgBTdHJlYW0gdG9vIHNob3J0LCBleHBlY3RlZCBTT1QKAFVuYWJsZSB0byBzZXQgdDEgaGFuZGxlIGFzIFRMUwoAU3RyZWFtIGRvZXMgbm90IGVuZCB3aXRoIEVPQwoAQ2Fubm90IGhhbmRsZSBib3ggc2l6ZXMgaGlnaGVyIHRoYW4gMl4zMgoAb3BqX3BpX25leHRfbHJjcCgpOiBpbnZhbGlkIGNvbXBubzAvY29tcG5vMQoAb3BqX3BpX25leHRfcmxjcCgpOiBpbnZhbGlkIGNvbXBubzAvY29tcG5vMQoAb3BqX3BpX25leHRfY3BybCgpOiBpbnZhbGlkIGNvbXBubzAvY29tcG5vMQoAb3BqX3BpX25leHRfcGNybCgpOiBpbnZhbGlkIGNvbXBubzAvY29tcG5vMQoAb3BqX3BpX25leHRfcnBjbCgpOiBpbnZhbGlkIGNvbXBubzAvY29tcG5vMQoAb3BqX3QxX2RlY29kZV9jYmxrKCk6IHVuc3VwcG9ydGVkIGJwbm9fcGx1c19vbmUgPSAlZCA+PSAzMQoARmFpbGVkIHRvIGRlY29kZSB0aWxlIDEvMQoASW5zdWZmaWNpZW50IGRhdGEgZm9yIENNQVAgYm94LgoATmVlZCB0byByZWFkIGEgUENMUiBib3ggYmVmb3JlIHRoZSBDTUFQIGJveC4KAEluc3VmZmljaWVudCBkYXRhIGZvciBDREVGIGJveC4KAE51bWJlciBvZiBjaGFubmVsIGRlc2NyaXB0aW9uIGlzIGVxdWFsIHRvIHplcm8gaW4gQ0RFRiBib3guCgBTdHJlYW0gZXJyb3Igd2hpbGUgcmVhZGluZyBKUDIgSGVhZGVyIGJveDogbm8gJ2loZHInIGJveC4KAE5vbiBjb25mb3JtYW50IGNvZGVzdHJlYW0gVFBzb3Q9PVROc290LgoAU3RyZWFtIGVycm9yIHdoaWxlIHJlYWRpbmcgSlAyIEhlYWRlciBib3g6IGJveCBsZW5ndGggaXMgaW5jb25zaXN0ZW50LgoAQm94IGxlbmd0aCBpcyBpbmNvbnNpc3RlbnQuCgBSZXNvbHV0aW9uIGZhY3RvciBpcyBncmVhdGVyIHRoYW4gdGhlIG1heGltdW0gcmVzb2x1dGlvbiBpbiB0aGUgY29tcG9uZW50LgoAQ29tcG9uZW50IG1hcHBpbmcgc2VlbXMgd3JvbmcuIFRyeWluZyB0byBjb3JyZWN0LgoASW5jb21wbGV0ZSBjaGFubmVsIGRlZmluaXRpb25zLgoATWFsZm9ybWVkIEhUIGNvZGVibG9jay4gSW52YWxpZCBjb2RlYmxvY2sgbGVuZ3RoIHZhbHVlcy4KAFdlIGRvIG5vdCBzdXBwb3J0IG1vcmUgdGhhbiAzIGNvZGluZyBwYXNzZXMgaW4gYW4gSFQgY29kZWJsb2NrOyBUaGlzIGNvZGVibG9ja3MgaGFzICVkIHBhc3Nlcy4KAE1hbGZvcm1lZCBIVCBjb2RlYmxvY2suIERlY29kaW5nIHRoaXMgY29kZWJsb2NrIGlzIHN0b3BwZWQuIFRoZXJlIGFyZSAlZCB6ZXJvIGJpdHBsYW5lcyBpbiAlZCBiaXRwbGFuZXMuCgBDYW5ub3QgdGFrZSBpbiBjaGFyZ2UgbXVsdGlwbGUgdHJhbnNmb3JtYXRpb24gc3RhZ2VzLgoAVW5rbm93biBtYXJrZXIgaGFzIGJlZW4gZGV0ZWN0ZWQgYW5kIGdlbmVyYXRlZCBlcnJvci4KAENvZGVjIHByb3ZpZGVkIHRvIHRoZSBvcGpfc2V0X2RlY29kZWRfY29tcG9uZW50cyBmdW5jdGlvbiBpcyBub3QgYSBkZWNvbXByZXNzb3IgaGFuZGxlci4KAENvZGVjIHByb3ZpZGVkIHRvIHRoZSBvcGpfc2V0dXBfZGVjb2RlciBmdW5jdGlvbiBpcyBub3QgYSBkZWNvbXByZXNzb3IgaGFuZGxlci4KAENvZGVjIHByb3ZpZGVkIHRvIHRoZSBvcGpfcmVhZF9oZWFkZXIgZnVuY3Rpb24gaXMgbm90IGEgZGVjb21wcmVzc29yIGhhbmRsZXIuCgBUaWxlcyBkb24ndCBhbGwgaGF2ZSB0aGUgc2FtZSBkaW1lbnNpb24uIFNraXAgdGhlIE1DVCBzdGVwLgoATnVtYmVyIG9mIGNvbXBvbmVudHMgKCVkKSBpcyBpbmNvbnNpc3RlbnQgd2l0aCBhIE1DVC4gU2tpcCB0aGUgTUNUIHN0ZXAuCgBKUDIgYm94IHdoaWNoIGFyZSBhZnRlciB0aGUgY29kZXN0cmVhbSB3aWxsIG5vdCBiZSByZWFkIGJ5IHRoaXMgZnVuY3Rpb24uCgBNYWxmb3JtZWQgSFQgY29kZWJsb2NrLiBXaGVuIHRoZSBudW1iZXIgb2YgemVybyBwbGFuZXMgYml0cGxhbmVzIGlzIGVxdWFsIHRvIHRoZSBudW1iZXIgb2YgYml0cGxhbmVzLCBvbmx5IHRoZSBjbGVhbnVwIHBhc3MgbWFrZXMgc2Vuc2UsIGJ1dCB3ZSBoYXZlICVkIHBhc3NlcyBpbiB0aGlzIGNvZGVibG9jay4gVGhlcmVmb3JlLCBvbmx5IHRoZSBjbGVhbnVwIHBhc3Mgd2lsbCBiZSBkZWNvZGVkLiBUaGlzIG1lc3NhZ2Ugd2lsbCBub3QgYmUgZGlzcGxheWVkIGFnYWluLgoASW1hZ2UgaGFzIGxlc3MgY29tcG9uZW50cyB0aGFuIGNvZGVzdHJlYW0uCgBOZWVkIHRvIGRlY29kZSB0aGUgbWFpbiBoZWFkZXIgYmVmb3JlIGJlZ2luIHRvIGRlY29kZSB0aGUgcmVtYWluaW5nIGNvZGVzdHJlYW0uCgBQc290IHZhbHVlIG9mIHRoZSBjdXJyZW50IHRpbGUtcGFydCBpcyBlcXVhbCB0byB6ZXJvLCB3ZSBhc3N1bWluZyBpdCBpcyB0aGUgbGFzdCB0aWxlLXBhcnQgb2YgdGhlIGNvZGVzdHJlYW0uCgBBIG1hbGZvcm1lZCBjb2RlYmxvY2sgdGhhdCBoYXMgbW9yZSB0aGFuIG9uZSBjb2RpbmcgcGFzcywgYnV0IHplcm8gbGVuZ3RoIGZvciAybmQgYW5kIHBvdGVudGlhbGx5IHRoZSAzcmQgcGFzcyBpbiBhbiBIVCBjb2RlYmxvY2suCgAJCQkgdGlsZS1wYXJ0WyVkXTogc3Rhcl9wb3M9JWxsaSwgZW5kX2hlYWRlcj0lbGxpLCBlbmRfcG9zPSVsbGkuCgBUaWxlICV1IGhhcyBUUHNvdCA9PSAwIGFuZCBUTnNvdCA9PSAwLCBidXQgbm8gb3RoZXIgdGlsZS1wYXJ0cyB3ZXJlIGZvdW5kLiBFT0MgaXMgYWxzbyBtaXNzaW5nLgoAQ29tcG9uZW50ICVkIGRvZXNuJ3QgaGF2ZSBhIG1hcHBpbmcuCgBBIGNvbmZvcm1pbmcgSlAyIHJlYWRlciBzaGFsbCBpZ25vcmUgYWxsIENvbG91ciBTcGVjaWZpY2F0aW9uIGJveGVzIGFmdGVyIHRoZSBmaXJzdCwgc28gd2UgaWdub3JlIHRoaXMgb25lLgoAVGhlIHNpZ25hdHVyZSBib3ggbXVzdCBiZSB0aGUgZmlyc3QgYm94IGluIHRoZSBmaWxlLgoAVGhlICBib3ggbXVzdCBiZSB0aGUgZmlyc3QgYm94IGluIHRoZSBmaWxlLgoAVGhlIGZ0eXAgYm94IG11c3QgYmUgdGhlIHNlY29uZCBib3ggaW4gdGhlIGZpbGUuCgBGYWlsZWQgdG8gZGVjb2RlLgoATWFsZm9ybWVkIEhUIGNvZGVibG9jay4gSW5jb3JyZWN0IE1FTCBzZWdtZW50IHNlcXVlbmNlLgoAQ29tcG9uZW50ICVkIGlzIG1hcHBlZCB0d2ljZS4KAE9ubHkgb25lIENNQVAgYm94IGlzIGFsbG93ZWQuCgBhcHBseV9jb2xvcl90cmFuc2Zvcm1zID0gT1BKX1RSVUUgaXMgbm90IHN1cHBvcnRlZC4KAFdlIG5lZWQgYW4gaW1hZ2UgcHJldmlvdXNseSBjcmVhdGVkLgoASUhEUiBib3hfbWlzc2luZy4gUmVxdWlyZWQuCgBKUDJIIGJveCBtaXNzaW5nLiBSZXF1aXJlZC4KAE5vdCBzdXJlIGhvdyB0aGF0IGhhcHBlbmVkLgoATWFpbiBoZWFkZXIgaGFzIGJlZW4gY29ycmVjdGx5IGRlY29kZWQuCgBUaWxlICVkLyVkIGhhcyBiZWVuIGRlY29kZWQuCgBIZWFkZXIgb2YgdGlsZSAlZCAvICVkIGhhcyBiZWVuIHJlYWQuCgBFbXB0eSBTT1QgbWFya2VyIGRldGVjdGVkOiBQc290PSVkLgoARGlyZWN0IHVzZSBhdCAjJWQgaG93ZXZlciBwY29sPSVkLgoASW1wbGVtZW50YXRpb24gbGltaXRhdGlvbjogZm9yIHBhbGV0dGUgbWFwcGluZywgcGNvbFslZF0gc2hvdWxkIGJlIGVxdWFsIHRvICVkLCBidXQgaXMgZXF1YWwgdG8gJWQuCgBJbnZhbGlkIGNvbXBvbmVudC9wYWxldHRlIGluZGV4IGZvciBkaXJlY3QgbWFwcGluZyAlZC4KAEludmFsaWQgdmFsdWUgZm9yIGNtYXBbJWRdLm10eXAgPSAlZC4KAFBzb3QgdmFsdWUgaXMgbm90IGNvcnJlY3QgcmVnYXJkcyB0byB0aGUgSlBFRzIwMDAgbm9ybTogJWQuCgBNYWxmb3JtZWQgSFQgY29kZWJsb2NrLiBWTEMgY29kZSBwcm9kdWNlcyBzaWduaWZpY2FudCBzYW1wbGVzIG91dHNpZGUgdGhlIGNvZGVibG9jayBhcmVhLgoAVW5leHBlY3RlZCBPT00uCgAzMiBiaXRzIGFyZSBub3QgZW5vdWdoIHRvIGRlY29kZSB0aGlzIGNvZGVibG9jaywgc2luY2UgdGhlIG51bWJlciBvZiBiaXRwbGFuZSwgJWQsIGlzIGxhcmdlciB0aGFuIDMwLgoAQm90dG9tIHBvc2l0aW9uIG9mIHRoZSBkZWNvZGVkIGFyZWEgKHJlZ2lvbl95MT0lZCkgc2hvdWxkIGJlID4gMC4KAFJpZ2h0IHBvc2l0aW9uIG9mIHRoZSBkZWNvZGVkIGFyZWEgKHJlZ2lvbl94MT0lZCkgc2hvdWxkIGJlID4gMC4KAFVwIHBvc2l0aW9uIG9mIHRoZSBkZWNvZGVkIGFyZWEgKHJlZ2lvbl95MD0lZCkgc2hvdWxkIGJlID49IDAuCgBMZWZ0IHBvc2l0aW9uIG9mIHRoZSBkZWNvZGVkIGFyZWEgKHJlZ2lvbl94MD0lZCkgc2hvdWxkIGJlID49IDAuCgBFcnJvciByZWFkaW5nIFBQVCBtYXJrZXI6IHBhY2tldCBoZWFkZXIgaGF2ZSBiZWVuIHByZXZpb3VzbHkgZm91bmQgaW4gdGhlIG1haW4gaGVhZGVyIChQUE0gbWFya2VyKS4KAFN0YXJ0IHRvIHJlYWQgajJrIG1haW4gaGVhZGVyICglbGxkKS4KAEJvdHRvbSBwb3NpdGlvbiBvZiB0aGUgZGVjb2RlZCBhcmVhIChyZWdpb25feTE9JWQpIGlzIG91dHNpZGUgdGhlIGltYWdlIGFyZWEgKFlzaXo9JWQpLgoAVXAgcG9zaXRpb24gb2YgdGhlIGRlY29kZWQgYXJlYSAocmVnaW9uX3kwPSVkKSBpcyBvdXRzaWRlIHRoZSBpbWFnZSBhcmVhIChZc2l6PSVkKS4KAFJpZ2h0IHBvc2l0aW9uIG9mIHRoZSBkZWNvZGVkIGFyZWEgKHJlZ2lvbl94MT0lZCkgaXMgb3V0c2lkZSB0aGUgaW1hZ2UgYXJlYSAoWHNpej0lZCkuCgBMZWZ0IHBvc2l0aW9uIG9mIHRoZSBkZWNvZGVkIGFyZWEgKHJlZ2lvbl94MD0lZCkgaXMgb3V0c2lkZSB0aGUgaW1hZ2UgYXJlYSAoWHNpej0lZCkuCgBCb3R0b20gcG9zaXRpb24gb2YgdGhlIGRlY29kZWQgYXJlYSAocmVnaW9uX3kxPSVkKSBpcyBvdXRzaWRlIHRoZSBpbWFnZSBhcmVhIChZT3Npej0lZCkuCgBVcCBwb3NpdGlvbiBvZiB0aGUgZGVjb2RlZCBhcmVhIChyZWdpb25feTA9JWQpIGlzIG91dHNpZGUgdGhlIGltYWdlIGFyZWEgKFlPc2l6PSVkKS4KAFJpZ2h0IHBvc2l0aW9uIG9mIHRoZSBkZWNvZGVkIGFyZWEgKHJlZ2lvbl94MT0lZCkgaXMgb3V0c2lkZSB0aGUgaW1hZ2UgYXJlYSAoWE9zaXo9JWQpLgoATGVmdCBwb3NpdGlvbiBvZiB0aGUgZGVjb2RlZCBhcmVhIChyZWdpb25feDA9JWQpIGlzIG91dHNpZGUgdGhlIGltYWdlIGFyZWEgKFhPc2l6PSVkKS4KAFNpemUgeCBvZiB0aGUgZGVjb2RlZCBjb21wb25lbnQgaW1hZ2UgaXMgaW5jb3JyZWN0IChjb21wWyVkXS53PSVkKS4KAFNpemUgeSBvZiB0aGUgZGVjb2RlZCBjb21wb25lbnQgaW1hZ2UgaXMgaW5jb3JyZWN0IChjb21wWyVkXS5oPSVkKS4KAFRpbGUgcmVhZCwgZGVjb2RlZCBhbmQgdXBkYXRlZCBpcyBub3QgdGhlIGRlc2lyZWQgb25lICglZCB2cyAlZCkuCgBJbnZhbGlkIGNvbXBvbmVudCBpbmRleCAlZCAoPj0gJWQpLgoAb3BqX3JlYWRfaGVhZGVyKCkgc2hvdWxkIGJlIGNhbGxlZCBiZWZvcmUgb3BqX3NldF9kZWNvZGVkX2NvbXBvbmVudHMoKS4KAE1lbW9yeSBhbGxvY2F0aW9uIGZhaWx1cmUgaW4gb3BqX2pwMl9hcHBseV9wY2xyKCkuCgBpbWFnZS0+Y29tcHNbJWRdLmRhdGEgPT0gTlVMTCBpbiBvcGpfanAyX2FwcGx5X3BjbHIoKS4KAGludmFsaWQgYm94IHNpemUgJWQgKCV4KQoARmFpbCB0byByZWFkIHRoZSBjdXJyZW50IG1hcmtlciBzZWdtZW50ICglI3gpCgBFcnJvciB3aXRoIFNJWiBtYXJrZXI6IElIRFIgdygldSkgaCgldSkgdnMuIFNJWiB3KCV1KSBoKCV1KQoARXJyb3IgcmVhZGluZyBDT0MgbWFya2VyIChiYWQgbnVtYmVyIG9mIGNvbXBvbmVudHMpCgBJbnZhbGlkIG51bWJlciBvZiB0aWxlcyA6ICV1IHggJXUgKG1heGltdW0gZml4ZWQgYnkganBlZzIwMDAgbm9ybSBpcyA2NTUzNSB0aWxlcykKAEludmFsaWQgbnVtYmVyIG9mIGNvbXBvbmVudHMgKGloZHIpCgBOb3QgZW5vdWdoIG1lbW9yeSB0byBoYW5kbGUgaW1hZ2UgaGVhZGVyIChpaGRyKQoAV3JvbmcgdmFsdWVzIGZvcjogdyglZCkgaCglZCkgbnVtY29tcHMoJWQpIChpaGRyKQoASW52YWxpZCB2YWx1ZXMgZm9yIGNvbXAgPSAlZCA6IGR4PSV1IGR5PSV1IChzaG91bGQgYmUgYmV0d2VlbiAxIGFuZCAyNTUgYWNjb3JkaW5nIHRvIHRoZSBKUEVHMjAwMCBub3JtKQoAQmFkIGltYWdlIGhlYWRlciBib3ggKGJhZCBzaXplKQoAQmFkIENPTFIgaGVhZGVyIGJveCAoYmFkIHNpemUpCgBCYWQgQlBDQyBoZWFkZXIgYm94IChiYWQgc2l6ZSkKAEVycm9yIHdpdGggU0laIG1hcmtlcjogbmVnYXRpdmUgb3IgemVybyBpbWFnZSBzaXplICglbGxkIHggJWxsZCkKAHNraXA6IHNlZ21lbnQgdG9vIGxvbmcgKCVkKSB3aXRoIG1heCAoJWQpIGZvciBjb2RlYmxvY2sgJWQgKHA9JWQsIGI9JWQsIHI9JWQsIGM9JWQpCgByZWFkOiBzZWdtZW50IHRvbyBsb25nICglZCkgd2l0aCBtYXggKCVkKSBmb3IgY29kZWJsb2NrICVkIChwPSVkLCBiPSVkLCByPSVkLCBjPSVkKQoARGVzcGl0ZSBKUDIgQlBDIT0yNTUsIHByZWNpc2lvbiBhbmQvb3Igc2duZCB2YWx1ZXMgZm9yIGNvbXBbJWRdIGlzIGRpZmZlcmVudCB0aGFuIGNvbXBbMF06CiAgICAgICAgWzBdIHByZWMoJWQpIHNnbmQoJWQpIFslZF0gcHJlYyglZCkgc2duZCglZCkKAGJhZCBjb21wb25lbnQgbnVtYmVyIGluIFJHTiAoJWQgd2hlbiB0aGVyZSBhcmUgb25seSAlZCkKAEVycm9yIHdpdGggU0laIG1hcmtlcjogbnVtYmVyIG9mIGNvbXBvbmVudCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoZSByZW1haW5pbmcgbnVtYmVyIG9mIHBhcmFtZXRlcnMgKCAlZCB2cyAlZCkKAEVycm9yIHdpdGggU0laIG1hcmtlcjogaW52YWxpZCB0aWxlIHNpemUgKHRkeDogJWQsIHRkeTogJWQpCgBCYWQgQ09MUiBoZWFkZXIgYm94IChiYWQgc2l6ZTogJWQpCgBCYWQgQ09MUiBoZWFkZXIgYm94IChDSUVMYWIsIGJhZCBzaXplOiAlZCkKAFBURVJNIGNoZWNrIGZhaWx1cmU6ICVkIHJlbWFpbmluZyBieXRlcyBpbiBjb2RlIGJsb2NrICglZCB1c2VkIC8gJWQpCgBNYWxmb3JtZWQgSFQgY29kZWJsb2NrLiBPbmUgb2YgdGhlIGZvbGxvd2luZyBjb25kaXRpb24gaXMgbm90IG1ldDogMiA8PSBTY3VwIDw9IG1pbihMY3VwLCA0MDc5KQoASW52YWxpZCB2YWx1ZXMgZm9yIGNvbXAgPSAlZCA6IHByZWM9JXUgKHNob3VsZCBiZSBiZXR3ZWVuIDEgYW5kIDM4IGFjY29yZGluZyB0byB0aGUgSlBFRzIwMDAgbm9ybS4gT3BlbkpwZWcgb25seSBzdXBwb3J0cyB1cCB0byAzMSkKAEludmFsaWQgYml0IG51bWJlciAlZCBpbiBvcGpfdDJfcmVhZF9wYWNrZXRfaGVhZGVyKCkKAFN0cmVhbSBlcnJvciEKAEVycm9yIG9uIHdyaXRpbmcgc3RyZWFtIQoAU3RyZWFtIHJlYWNoZWQgaXRzIGVuZCAhCgBFeHBlY3RlZCBhIFNPQyBtYXJrZXIgCgBJbnZhbGlkIGJveCBzaXplICVkIGZvciBib3ggJyVjJWMlYyVjJy4gTmVlZCAlZCBieXRlcywgJWQgYnl0ZXMgcmVtYWluaW5nIAoATWFsZm9ybWVkIEhUIGNvZGVibG9jay4gRGVjb2RpbmcgdGhpcyBjb2RlYmxvY2sgaXMgc3RvcHBlZC4gVV9xIGlzIGxhcmdlciB0aGFuIHplcm8gYml0cGxhbmVzICsgMSAKAE1hbGZvcm1lZCBIVCBjb2RlYmxvY2suIERlY29kaW5nIHRoaXMgY29kZWJsb2NrIGlzIHN0b3BwZWQuIFVfcSBpc2xhcmdlciB0aGFuIGJpdHBsYW5lcyArIDEgCgBDT0xSIEJPWCBtZXRoIHZhbHVlIGlzIG5vdCBhIHJlZ3VsYXIgdmFsdWUgKCVkKSwgc28gd2Ugd2lsbCBpZ25vcmUgdGhlIGVudGlyZSBDb2xvdXIgU3BlY2lmaWNhdGlvbiBib3guIAoAV2hpbGUgcmVhZGluZyBDQ1BfUU5UU1RZIGVsZW1lbnQgaW5zaWRlIFFDRCBvciBRQ0MgbWFya2VyIHNlZ21lbnQsIG51bWJlciBvZiBzdWJiYW5kcyAoJWQpIGlzIGdyZWF0ZXIgdG8gT1BKX0oyS19NQVhCQU5EUyAoJWQpLiBTbyB3ZSBsaW1pdCB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIHN0b3JlZCB0byBPUEpfSjJLX01BWEJBTkRTICglZCkgYW5kIHNraXAgdGhlIHJlc3QuIAoASlAyIElIRFIgYm94OiBjb21wcmVzc2lvbiB0eXBlIGluZGljYXRlIHRoYXQgdGhlIGZpbGUgaXMgbm90IGEgY29uZm9ybWluZyBKUDIgZmlsZSAoJWQpIAoAVGlsZSBpbmRleCBwcm92aWRlZCBieSB0aGUgdXNlciBpcyBpbmNvcnJlY3QgJWQgKG1heCA9ICVkKSAKAEVycm9yIGRlY29kaW5nIGNvbXBvbmVudCAlZC4KVGhlIG51bWJlciBvZiByZXNvbHV0aW9ucyB0byByZW1vdmUgKCVkKSBpcyBncmVhdGVyIG9yIGVxdWFsIHRoYW4gdGhlIG51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4E8AANBPAAABVgAAAQAAAPBPAADATwAAAVQAAAAAAAAAUAAAwFAAAAFUAAABAAAAEFAAANBQAAABSAAAAAAAACBQAADAUAAAAUgAAAEAAAAwUAAA0FAAAAE4AAAAAAAAQFAAAMBQAAABOAAAAQAAAFBQAADQUAAAATAAAAAAAABgUAAAIFEAAAEwAAABAAAAcFAAADBRAAABJAAAAAAAAIBQAABAUQAAASQAAAEAAACQUAAAUFEAAAEcAAAAAAAAoFAAAIBRAAABHAAAAQAAALBQAACQUQAAARYAAAAAAACgUgAAoFEAAAEWAAABAAAAsFIAALBRAAABVgAAAAAAAOBQAADQUAAAAVYAAAEAAADwUAAAwFAAAAFUAAAAAAAAAFEAAMBQAAABVAAAAQAAABBRAADQUAAAAVEAAAAAAAAgUQAA4FAAAAFRAAABAAAAMFEAAPBQAAABSAAAAAAAAEBRAAAAUQAAAUgAAAEAAABQUQAAEFEAAAE4AAAAAAAAYFEAACBRAAABOAAAAQAAAHBRAAAwUQAAATQAAAAAAACAUQAAQFEAAAE0AAABAAAAkFEAAFBRAAABMAAAAAAAAKBRAABgUQAAATAAAAEAAACwUQAAcFEAAAEoAAAAAAAAwFEAAGBRAAABKAAAAQAAANBRAABwUQAAASQAAAAAAADgUQAAgFEAAAEkAAABAAAA8FEAAJBRAAABIgAAAAAAAABSAACgUQAAASIAAAEAAAAQUgAAsFEAAAEcAAAAAAAAIFIAAMBRAAABHAAAAQAAADBSAADQUQAAARgAAAAAAABAUgAA4FEAAAEYAAABAAAAUFIAAPBRAAABFgAAAAAAAGBSAAAAUgAAARYAAAEAAABwUgAAEFIAAAEUAAAAAAAAgFIAACBSAAABFAAAAQAAAJBSAAAwUgAAARIAAAAAAACgUgAAQFIAAAESAAABAAAAsFIAAFBSAAABEQAAAAAAAMBSAABgUgAAAREAAAEAAADQUgAAcFIAAMEKAAAAAAAA4FIAAIBSAADBCgAAAQAAAPBSAACQUgAAwQkAAAAAAAAAUwAAoFIAAMEJAAABAAAAEFMAALBSAAChCAAAAAAAACBTAADAUgAAoQgAAAEAAAAwUwAA0FIAACEFAAAAAAAAQFMAAOBSAAAhBQAAAQAAAFBTAADwUgAAQQQAAAAAAABgUwAAAFMAAEEEAAABAAAAcFMAABBTAAChAgAAAAAAAIBTAAAgUwAAoQIAAAEAAACQUwAAMFMAACECAAAAAAAAoFMAAEBTAAAhAgAAAQAAALBTAABQUwAAQQEAAAAAAADAUwAAYFMAAEEBAAABAAAA0FMAAHBTAAARAQAAAAAAAOBTAACAUwAAEQEAAAEAAADwUwAAkFMAAIUAAAAAAAAAAFQAAKBTAACFAAAAAQAAABBUAACwUwAASQAAAAAAAAAgVAAAwFMAAEkAAAABAAAAMFQAANBTAAAlAAAAAAAAAEBUAADgUwAAJQAAAAEAAABQVAAA8FMAABUAAAAAAAAAYFQAAABUAAAVAAAAAQAAAHBUAAAQVAAACQAAAAAAAACAVAAAIFQAAAkAAAABAAAAkFQAADBUAAAFAAAAAAAAAKBUAABAVAAABQAAAAEAAACwVAAAUFQAAAEAAAAAAAAAoFQAAGBUAAABAAAAAQAAALBUAABwVAAAAVYAAAAAAADAVAAAwFQAAAFWAAABAAAA0FQAANBUAAAAAQMDAQIDAwUGBwcGBgcHAAEDAwECAwMFBgcHBgYHBwUGBwcGBgcHCAgICAgICAgFBgcHBgYHBwgICAgICAgIAQIDAwICAwMGBgcHBgYHBwECAwMCAgMDBgYHBwYGBwcGBgcHBgYHBwgICAgICAgIBgYHBwYGBwcICAgICAgICAMDBAQDAwQEBwcHBwcHBwcDAwQEAwMEBAcHBwcHBwcHBwcHBwcHBwcICAgICAgICAcHBwcHBwcHCAgICAgICAgDAwQEAwMEBAcHBwcHBwcHAwMEBAMDBAQHBwcHBwcHBwcHBwcHBwcHCAgICAgICAgHBwcHBwcHBwgICAgICAgIAQIDAwICAwMGBgcHBgYHBwECAwMCAgMDBgYHBwYGBwcGBgcHBgYHBwgICAgICAgIBgYHBwYGBwcICAgICAgICAICAwMCAgMDBgYHBwYGBwcCAgMDAgIDAwYGBwcGBgcHBgYHBwYGBwcICAgICAgICAYGBwcGBgcHCAgICAgICAgDAwQEAwMEBAcHBwcHBwcHAwMEBAMDBAQHBwcHBwcHBwcHBwcHBwcHCAgICAgICAgHBwcHBwcHBwgICAgICAgIAwMEBAMDBAQHBwcHBwcHBwMDBAQDAwQEBwcHBwcHBwcHBwcHBwcHBwgICAgICAgIBwcHBwcHBwcICAgICAgICAABBQYBAgYGAwMHBwMDBwcAAQUGAQIGBgMDBwcDAwcHAwMHBwMDBwcEBAcHBAQHBwMDBwcDAwcHBAQHBwQEBwcBAgYGAgIGBgMDBwcDAwcHAQIGBgICBgYDAwcHAwMHBwMDBwcDAwcHBAQHBwQEBwcDAwcHAwMHBwQEBwcEBAcHBQYICAYGCAgHBwgIBwcICAUGCAgGBggIBwcICAcHCAgHBwgIBwcICAcHCAgHBwgIBwcICAcHCAgHBwgIBwcICAYGCAgGBggIBwcICAcHCAgGBggIBgYICAcHCAgHBwgIBwcICAcHCAgHBwgIBwcICAcHCAgHBwgIBwcICAcHCAgBAgYGAgIGBgMDBwcDAwcHAQIGBgICBgYDAwcHAwMHBwMDBwcDAwcHBAQHBwQEBwcDAwcHAwMHBwQEBwcEBAcHAgIGBgICBgYDAwcHAwMHBwICBgYCAgYGAwMHBwMDBwcDAwcHAwMHBwQEBwcEBAcHAwMHBwMDBwcEBAcHBAQHBwYGCAgGBggIBwcICAcHCAgGBggIBgYICAcHCAgHBwgIBwcICAcHCAgHBwgIBwcICAcHCAgHBwgIBwcICAcHCAgGBggIBgYICAcHCAgHBwgIBgYICAYGCAgHBwgIBwcICAcHCAgHBwgIBwcICAcHCAgHBwgIBwcICAcHCAgHBwgIAAEDAwECAwMFBgcHBgYHBwABAwMBAgMDBQYHBwYGBwcFBgcHBgYHBwgICAgICAgIBQYHBwYGBwcICAgICAgICAECAwMCAgMDBgYHBwYGBwcBAgMDAgIDAwYGBwcGBgcHBgYHBwYGBwcICAgICAgICAYGBwcGBgcHCAgICAgICAgDAwQEAwMEBAcHBwcHBwcHAwMEBAMDBAQHBwcHBwcHBwcHBwcHBwcHCAgICAgICAgHBwcHBwcHBwgICAgICAgIAwMEBAMDBAQHBwcHBwcHBwMDBAQDAwQEBwcHBwcHBwcHBwcHBwcHBwgICAgICAgIBwcHBwcHBwcICAgICAgICAECAwMCAgMDBgYHBwYGBwcBAgMDAgIDAwYGBwcGBgcHBgYHBwYGBwcICAgICAgICAYGBwcGBgcHCAgICAgICAgCAgMDAgIDAwYGBwcGBgcHAgIDAwICAwMGBgcHBgYHBwYGBwcGBgcHCAgICAgICAgGBgcHBgYHBwgICAgICAgIAwMEBAMDBAQHBwcHBwcHBwMDBAQDAwQEBwcHBwcHBwcHBwcHBwcHBwgICAgICAgIBwcHBwcHBwcICAgICAgICAMDBAQDAwQEBwcHBwcHBwcDAwQEAwMEBAcHBwcHBwcHBwcHBwcHBwcICAgICAgICAcHBwcHBwcHCAgICAgICAgAAwEEAwYEBwEEAgUEBwUHAAMBBAMGBAcBBAIFBAcFBwEEAgUEBwUHAgUCBQUHBQcBBAIFBAcFBwIFAgUFBwUHAwYEBwYIBwgEBwUHBwgHCAMGBAcGCAcIBAcFBwcIBwgEBwUHBwgHCAUHBQcHCAcIBAcFBwcIBwgFBwUHBwgHCAEEAgUEBwUHAgUCBQUHBQcBBAIFBAcFBwIFAgUFBwUHAgUCBQUHBQcCBQIFBQcFBwIFAgUFBwUHAgUCBQUHBQcEBwUHBwgHCAUHBQcHCAcIBAcFBwcIBwgFBwUHBwgHCAUHBQcHCAcIBQcFBwcIBwgFBwUHBwgHCAUHBQcHCAcIAwYEBwYIBwgEBwUHBwgHCAMGBAcGCAcIBAcFBwcIBwgEBwUHBwgHCAUHBQcHCAcIBAcFBwcIBwgFBwUHBwgHCAYIBwgICAgIBwgHCAgICAgGCAcICAgICAcIBwgICAgIBwgHCAgICAgHCAcICAgICAcIBwgICAgIBwgHCAgICAgEBwUHBwgHCAUHBQcHCAcIBAcFBwcIBwgFBwUHBwgHCAUHBQcHCAcIBQcFBwcIBwgFBwUHBwgHCAUHBQcHCAcIBwgHCAgICAgHCAcICAgICAcIBwgICAgIBwgHCAgICAgHCAcICAgICAcIBwgICAgIBwgHCAgICAgHCAcICAgICAkJCgoJCQoKDAwNCwwMDQsJCQoKCQkKCgwMCw0MDAsNDAwNDQwMCwsMCQ0KCQwKCwwMCwsMDA0NDAkLCgkMCg0JCQoKCQkKCgwMDQsMDA0LCQkKCgkJCgoMDAsNDAwLDQwMDQ0MDAsLDAkNCgkMCgsMDAsLDAwNDQwJCwoJDAoNCgoKCgoKCgoNCw0LDQsNCwoKCQkKCgkJDQsMDA0LDAwNDQ0NCwsLCw0KDQoKCwoLDQ0MDAsLDAwNCgwJCgsJDAoKCQkKCgkJCw0MDAsNDAwKCgoKCgoKCgsNCw0LDQsNCwsMDA0NDAwLCgwJCg0JDAsLCwsNDQ0NCwoLCgoNCg0AQem7AQs3AQABAAEAAQAAAQEAAAEBAAEAAQABAAEAAAAAAQEBAQAAAAAAAQABAAAAAAEBAQEAAAABAAEBAQBBqbwBCzcBAAEAAQABAAABAQAAAQEAAQABAAEAAQAAAAABAQEBAAAAAAABAAEAAAAAAQEBAQAAAAEAAQEBAEHpvAELBwEAAQABAAEAQfm8AQuVAgEAAQABAAEAAAAAAQEBAQAAAAAAAQABAAAAAAEBAQEAAAAAAAEAAQEBAAABAQAAAAEAAQABAAEBAQEBAQEBAQABAAEAAQABAAAAAAEBAQEAAQAAAQEAAQAAAAABAQEBAAEAAQEBAQECAAAABAAAAAQAAAAIAAAAkP8AAAwAAAAYAAAAUv8AABQAAAAZAAAAU/8AABQAAAAaAAAAXv8AABQAAAAbAAAAXP8AABQAAAAcAAAAXf8AABQAAAAdAAAAX/8AABQAAAAeAAAAUf8AAAIAAAAfAAAAVf8AAAQAAAAgAAAAV/8AAAQAAAAhAAAAWP8AABAAAAAiAAAAYP8AAAQAAAAjAAAAYf8AABAAAAAkAAAAkf8AQZi/AQtlY/8AAAQAAAAlAAAAZP8AABQAAAAmAAAAdP8AABQAAAAnAAAAeP8AAAQAAAAoAAAAUP8AAAQAAAApAAAAWf8AAAQAAAAqAAAAdf8AABQAAAArAAAAd/8AABQAAAAsAAAAAAAAABQAQZDAAQs1LQAAAC4AAAAvAAAAMAAAADEAAAAyAAAAMwAAADQAAAAgIFBqNgAAAHB5dGY3AAAAaDJwajgAQdDAAQsycmRoaTkAAABybG9jOgAAAGNjcGI7AAAAcmxjcDwAAABwYW1jPQAAAGZlZGM+AAAAeGIAQZDBAQtBGQALABkZGQAAAAAFAAAAAAAACQAAAAALAAAAAAAAAAAZAAoKGRkZAwoHAAEACQsYAAAJBgsAAAsABhkAAAAZGRkAQeHBAQshDgAAAAAAAAAAGQALDRkZGQANAAACAAkOAAAACQAOAAAOAEGbwgELAQwAQafCAQsVEwAAAAATAAAAAAkMAAAAAAAMAAAMAEHVwgELARAAQeHCAQsVDwAAAAQPAAAAAAkQAAAAAAAQAAAQAEGPwwELARIAQZvDAQseEQAAAAARAAAAAAkSAAAAAAASAAASAAAaAAAAGhoaAEHSwwELDhoAAAAaGhoAAAAAAAAJAEGDxAELARQAQY/EAQsVFwAAAAAXAAAAAAkUAAAAAAAUAAAUAEG9xAELARYAQcnEAQsnFQAAAAAVAAAAAAkWAAAAAAAWAAAWAAAwMTIzNDU2Nzg5QUJDREVGAEHxxAELCGwBAAAAAAAFAEGExQELAWkAQZzFAQsOagAAAGsAAAD4ZwAAAAQAQbTFAQsBAQBBxMUBCwX/////Cg==\";\n    function getBinarySync(file) {\n      if (file == wasmBinaryFile && wasmBinary) {\n        return new Uint8Array(wasmBinary);\n      }\n      var binary = tryParseAsDataURI(file);\n      if (binary) {\n        return binary;\n      }\n      if (readBinary) {\n        return readBinary(file);\n      }\n      throw 'sync fetching of the wasm failed: you can preload it to Module[\"wasmBinary\"] manually, or emcc.py will do that for you when generating HTML (but not JS)';\n    }\n    function instantiateSync(file, info) {\n      var module;\n      var binary = getBinarySync(file);\n      module = new WebAssembly.Module(binary);\n      var instance = new WebAssembly.Instance(module, info);\n      return [instance, module];\n    }\n    function createWasm() {\n      var info = {\n        \"a\": wasmImports\n      };\n      function receiveInstance(instance, module) {\n        wasmExports = instance.exports;\n        wasmMemory = wasmExports[\"i\"];\n        updateMemoryViews();\n        addOnInit(wasmExports[\"j\"]);\n        removeRunDependency(\"wasm-instantiate\");\n        return wasmExports;\n      }\n      addRunDependency(\"wasm-instantiate\");\n      if (Module[\"instantiateWasm\"]) {\n        try {\n          return Module[\"instantiateWasm\"](info, receiveInstance);\n        } catch (e) {\n          err(`Module.instantiateWasm callback failed with error: ${e}`);\n          readyPromiseReject(e);\n        }\n      }\n      var result = instantiateSync(wasmBinaryFile, info);\n      return receiveInstance(result[0]);\n    }\n    var callRuntimeCallbacks = callbacks => {\n      while (callbacks.length > 0) {\n        callbacks.shift()(Module);\n      }\n    };\n    var noExitRuntime = Module[\"noExitRuntime\"] || true;\n    var __emscripten_memcpy_js = (dest, src, num) => HEAPU8.copyWithin(dest, src, src + num);\n    var getHeapMax = () => 2147483648;\n    var growMemory = size => {\n      var b = wasmMemory.buffer;\n      var pages = (size - b.byteLength + 65535) / 65536;\n      try {\n        wasmMemory.grow(pages);\n        updateMemoryViews();\n        return 1;\n      } catch (e) {}\n    };\n    var _emscripten_resize_heap = requestedSize => {\n      var oldSize = HEAPU8.length;\n      requestedSize >>>= 0;\n      var maxHeapSize = getHeapMax();\n      if (requestedSize > maxHeapSize) {\n        return false;\n      }\n      var alignUp = (x, multiple) => x + (multiple - x % multiple) % multiple;\n      for (var cutDown = 1; cutDown <= 4; cutDown *= 2) {\n        var overGrownHeapSize = oldSize * (1 + .2 / cutDown);\n        overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296);\n        var newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536));\n        var replacement = growMemory(newSize);\n        if (replacement) {\n          return true;\n        }\n      }\n      return false;\n    };\n    var ENV = {};\n    var getExecutableName = () => thisProgram || \"./this.program\";\n    var getEnvStrings = () => {\n      if (!getEnvStrings.strings) {\n        var lang = (typeof navigator == \"object\" && navigator.languages && navigator.languages[0] || \"C\").replace(\"-\", \"_\") + \".UTF-8\";\n        var env = {\n          \"USER\": \"web_user\",\n          \"LOGNAME\": \"web_user\",\n          \"PATH\": \"/\",\n          \"PWD\": \"/\",\n          \"HOME\": \"/home/web_user\",\n          \"LANG\": lang,\n          \"_\": getExecutableName()\n        };\n        for (var x in ENV) {\n          if (ENV[x] === undefined) delete env[x];else env[x] = ENV[x];\n        }\n        var strings = [];\n        for (var x in env) {\n          strings.push(`${x}=${env[x]}`);\n        }\n        getEnvStrings.strings = strings;\n      }\n      return getEnvStrings.strings;\n    };\n    var stringToAscii = (str, buffer) => {\n      for (var i = 0; i < str.length; ++i) {\n        HEAP8[buffer++] = str.charCodeAt(i);\n      }\n      HEAP8[buffer] = 0;\n    };\n    var _environ_get = (__environ, environ_buf) => {\n      var bufSize = 0;\n      getEnvStrings().forEach((string, i) => {\n        var ptr = environ_buf + bufSize;\n        HEAPU32[__environ + i * 4 >> 2] = ptr;\n        stringToAscii(string, ptr);\n        bufSize += string.length + 1;\n      });\n      return 0;\n    };\n    var _environ_sizes_get = (penviron_count, penviron_buf_size) => {\n      var strings = getEnvStrings();\n      HEAPU32[penviron_count >> 2] = strings.length;\n      var bufSize = 0;\n      strings.forEach(string => bufSize += string.length + 1);\n      HEAPU32[penviron_buf_size >> 2] = bufSize;\n      return 0;\n    };\n    var printCharBuffers = [null, [], []];\n    var UTF8Decoder = typeof TextDecoder != \"undefined\" ? new TextDecoder(\"utf8\") : undefined;\n    var UTF8ArrayToString = (heapOrArray, idx, maxBytesToRead) => {\n      var endIdx = idx + maxBytesToRead;\n      var endPtr = idx;\n      while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr;\n      if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {\n        return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));\n      }\n      var str = \"\";\n      while (idx < endPtr) {\n        var u0 = heapOrArray[idx++];\n        if (!(u0 & 128)) {\n          str += String.fromCharCode(u0);\n          continue;\n        }\n        var u1 = heapOrArray[idx++] & 63;\n        if ((u0 & 224) == 192) {\n          str += String.fromCharCode((u0 & 31) << 6 | u1);\n          continue;\n        }\n        var u2 = heapOrArray[idx++] & 63;\n        if ((u0 & 240) == 224) {\n          u0 = (u0 & 15) << 12 | u1 << 6 | u2;\n        } else {\n          u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heapOrArray[idx++] & 63;\n        }\n        if (u0 < 65536) {\n          str += String.fromCharCode(u0);\n        } else {\n          var ch = u0 - 65536;\n          str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023);\n        }\n      }\n      return str;\n    };\n    var printChar = (stream, curr) => {\n      var buffer = printCharBuffers[stream];\n      if (curr === 0 || curr === 10) {\n        (stream === 1 ? out : err)(UTF8ArrayToString(buffer, 0));\n        buffer.length = 0;\n      } else {\n        buffer.push(curr);\n      }\n    };\n    var UTF8ToString = (ptr, maxBytesToRead) => ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : \"\";\n    var _fd_write = (fd, iov, iovcnt, pnum) => {\n      var num = 0;\n      for (var i = 0; i < iovcnt; i++) {\n        var ptr = HEAPU32[iov >> 2];\n        var len = HEAPU32[iov + 4 >> 2];\n        iov += 8;\n        for (var j = 0; j < len; j++) {\n          printChar(fd, HEAPU8[ptr + j]);\n        }\n        num += len;\n      }\n      HEAPU32[pnum >> 2] = num;\n      return 0;\n    };\n    function _jsPrintWarning(message_ptr) {\n      const message = UTF8ToString(message_ptr);\n      (Module.warn || console.warn)(`OpenJPEG: ${message}`);\n    }\n    function _setImageData(array_ptr, array_size) {\n      Module.imageData = new Uint8ClampedArray(Module.HEAPU8.subarray(array_ptr, array_ptr + array_size));\n    }\n    function _storeErrorMessage(message_ptr) {\n      const message = UTF8ToString(message_ptr);\n      if (!Module.errorMessages) {\n        Module.errorMessages = message;\n      } else {\n        Module.errorMessages += \"\\n\" + message;\n      }\n    }\n    var wasmImports = {\n      f: __emscripten_memcpy_js,\n      b: _emscripten_resize_heap,\n      c: _environ_get,\n      d: _environ_sizes_get,\n      e: _fd_write,\n      g: _jsPrintWarning,\n      h: _setImageData,\n      a: _storeErrorMessage\n    };\n    var wasmExports = createWasm();\n    var ___wasm_call_ctors = wasmExports[\"j\"];\n    var _malloc = Module[\"_malloc\"] = wasmExports[\"k\"];\n    var _free = Module[\"_free\"] = wasmExports[\"l\"];\n    var _jp2_decode = Module[\"_jp2_decode\"] = wasmExports[\"n\"];\n    var __emscripten_stack_restore = wasmExports[\"_emscripten_stack_restore\"];\n    var __emscripten_stack_alloc = wasmExports[\"_emscripten_stack_alloc\"];\n    var _emscripten_stack_get_current = wasmExports[\"emscripten_stack_get_current\"];\n    var calledRun;\n    dependenciesFulfilled = function runCaller() {\n      if (!calledRun) run();\n      if (!calledRun) dependenciesFulfilled = runCaller;\n    };\n    function run() {\n      if (runDependencies > 0) {\n        return;\n      }\n      preRun();\n      if (runDependencies > 0) {\n        return;\n      }\n      function doRun() {\n        if (calledRun) return;\n        calledRun = true;\n        Module[\"calledRun\"] = true;\n        if (ABORT) return;\n        initRuntime();\n        readyPromiseResolve(Module);\n        if (Module[\"onRuntimeInitialized\"]) Module[\"onRuntimeInitialized\"]();\n        postRun();\n      }\n      if (Module[\"setStatus\"]) {\n        Module[\"setStatus\"](\"Running...\");\n        setTimeout(function () {\n          setTimeout(function () {\n            Module[\"setStatus\"](\"\");\n          }, 1);\n          doRun();\n        }, 1);\n      } else {\n        doRun();\n      }\n    }\n    if (Module[\"preInit\"]) {\n      if (typeof Module[\"preInit\"] == \"function\") Module[\"preInit\"] = [Module[\"preInit\"]];\n      while (Module[\"preInit\"].length > 0) {\n        Module[\"preInit\"].pop()();\n      }\n    }\n    run();\n    return moduleArg;\n  };\n})();\n/* harmony default export */ const openjpeg = (OpenJPEG);\n;// ./src/core/jpx.js\n\n\n\nclass JpxError extends BaseException {\n  constructor(msg) {\n    super(msg, \"JpxError\");\n  }\n}\nclass JpxImage {\n  static #module = null;\n  static decode(data, ignoreColorSpace = false) {\n    this.#module ||= openjpeg({\n      warn: warn\n    });\n    const imageData = this.#module.decode(data, ignoreColorSpace);\n    if (typeof imageData === \"string\") {\n      throw new JpxError(imageData);\n    }\n    return imageData;\n  }\n  static cleanup() {\n    this.#module = null;\n  }\n  static parseImageProperties(stream) {\n    let newByte = stream.getByte();\n    while (newByte >= 0) {\n      const oldByte = newByte;\n      newByte = stream.getByte();\n      const code = oldByte << 8 | newByte;\n      if (code === 0xff51) {\n        stream.skip(4);\n        const Xsiz = stream.getInt32() >>> 0;\n        const Ysiz = stream.getInt32() >>> 0;\n        const XOsiz = stream.getInt32() >>> 0;\n        const YOsiz = stream.getInt32() >>> 0;\n        stream.skip(16);\n        const Csiz = stream.getUint16();\n        return {\n          width: Xsiz - XOsiz,\n          height: Ysiz - YOsiz,\n          bitsPerComponent: 8,\n          componentsCount: Csiz\n        };\n      }\n    }\n    throw new JpxError(\"No size marker found in JPX stream\");\n  }\n}\n\n;// ./src/core/jpx_stream.js\n\n\n\nclass JpxStream extends DecodeStream {\n  constructor(stream, maybeLength, params) {\n    super(maybeLength);\n    this.stream = stream;\n    this.dict = stream.dict;\n    this.maybeLength = maybeLength;\n    this.params = params;\n  }\n  get bytes() {\n    try {\n      return shadow(this, \"bytes\", this.stream.getByteRange(this.stream.start, this.stream.start + this.maybeLength));\n    } catch (err) {\n      if (!(err instanceof Error) || !err.message.includes(\"Abstract method\")) {\n        throw err;\n      }\n    }\n    return shadow(this, \"bytes\", this.stream.getBytes(this.maybeLength));\n  }\n  ensureBuffer(requested) {}\n  readBlock(ignoreColorSpace) {\n    if (this.eof) {\n      return;\n    }\n    this.buffer = JpxImage.decode(this.bytes, ignoreColorSpace);\n    this.bufferLength = this.buffer.length;\n    this.eof = true;\n  }\n}\n\n;// ./src/core/lzw_stream.js\n\nclass LZWStream extends DecodeStream {\n  constructor(str, maybeLength, earlyChange) {\n    super(maybeLength);\n    this.str = str;\n    this.dict = str.dict;\n    this.cachedData = 0;\n    this.bitsCached = 0;\n    const maxLzwDictionarySize = 4096;\n    const lzwState = {\n      earlyChange,\n      codeLength: 9,\n      nextCode: 258,\n      dictionaryValues: new Uint8Array(maxLzwDictionarySize),\n      dictionaryLengths: new Uint16Array(maxLzwDictionarySize),\n      dictionaryPrevCodes: new Uint16Array(maxLzwDictionarySize),\n      currentSequence: new Uint8Array(maxLzwDictionarySize),\n      currentSequenceLength: 0\n    };\n    for (let i = 0; i < 256; ++i) {\n      lzwState.dictionaryValues[i] = i;\n      lzwState.dictionaryLengths[i] = 1;\n    }\n    this.lzwState = lzwState;\n  }\n  readBits(n) {\n    let bitsCached = this.bitsCached;\n    let cachedData = this.cachedData;\n    while (bitsCached < n) {\n      const c = this.str.getByte();\n      if (c === -1) {\n        this.eof = true;\n        return null;\n      }\n      cachedData = cachedData << 8 | c;\n      bitsCached += 8;\n    }\n    this.bitsCached = bitsCached -= n;\n    this.cachedData = cachedData;\n    this.lastCode = null;\n    return cachedData >>> bitsCached & (1 << n) - 1;\n  }\n  readBlock() {\n    const blockSize = 512,\n      decodedSizeDelta = blockSize;\n    let estimatedDecodedSize = blockSize * 2;\n    let i, j, q;\n    const lzwState = this.lzwState;\n    if (!lzwState) {\n      return;\n    }\n    const earlyChange = lzwState.earlyChange;\n    let nextCode = lzwState.nextCode;\n    const dictionaryValues = lzwState.dictionaryValues;\n    const dictionaryLengths = lzwState.dictionaryLengths;\n    const dictionaryPrevCodes = lzwState.dictionaryPrevCodes;\n    let codeLength = lzwState.codeLength;\n    let prevCode = lzwState.prevCode;\n    const currentSequence = lzwState.currentSequence;\n    let currentSequenceLength = lzwState.currentSequenceLength;\n    let decodedLength = 0;\n    let currentBufferLength = this.bufferLength;\n    let buffer = this.ensureBuffer(this.bufferLength + estimatedDecodedSize);\n    for (i = 0; i < blockSize; i++) {\n      const code = this.readBits(codeLength);\n      const hasPrev = currentSequenceLength > 0;\n      if (code < 256) {\n        currentSequence[0] = code;\n        currentSequenceLength = 1;\n      } else if (code >= 258) {\n        if (code < nextCode) {\n          currentSequenceLength = dictionaryLengths[code];\n          for (j = currentSequenceLength - 1, q = code; j >= 0; j--) {\n            currentSequence[j] = dictionaryValues[q];\n            q = dictionaryPrevCodes[q];\n          }\n        } else {\n          currentSequence[currentSequenceLength++] = currentSequence[0];\n        }\n      } else if (code === 256) {\n        codeLength = 9;\n        nextCode = 258;\n        currentSequenceLength = 0;\n        continue;\n      } else {\n        this.eof = true;\n        delete this.lzwState;\n        break;\n      }\n      if (hasPrev) {\n        dictionaryPrevCodes[nextCode] = prevCode;\n        dictionaryLengths[nextCode] = dictionaryLengths[prevCode] + 1;\n        dictionaryValues[nextCode] = currentSequence[0];\n        nextCode++;\n        codeLength = nextCode + earlyChange & nextCode + earlyChange - 1 ? codeLength : Math.min(Math.log(nextCode + earlyChange) / 0.6931471805599453 + 1, 12) | 0;\n      }\n      prevCode = code;\n      decodedLength += currentSequenceLength;\n      if (estimatedDecodedSize < decodedLength) {\n        do {\n          estimatedDecodedSize += decodedSizeDelta;\n        } while (estimatedDecodedSize < decodedLength);\n        buffer = this.ensureBuffer(this.bufferLength + estimatedDecodedSize);\n      }\n      for (j = 0; j < currentSequenceLength; j++) {\n        buffer[currentBufferLength++] = currentSequence[j];\n      }\n    }\n    lzwState.nextCode = nextCode;\n    lzwState.codeLength = codeLength;\n    lzwState.prevCode = prevCode;\n    lzwState.currentSequenceLength = currentSequenceLength;\n    this.bufferLength = currentBufferLength;\n  }\n}\n\n;// ./src/core/predictor_stream.js\n\n\n\nclass PredictorStream extends DecodeStream {\n  constructor(str, maybeLength, params) {\n    super(maybeLength);\n    if (!(params instanceof Dict)) {\n      return str;\n    }\n    const predictor = this.predictor = params.get(\"Predictor\") || 1;\n    if (predictor <= 1) {\n      return str;\n    }\n    if (predictor !== 2 && (predictor < 10 || predictor > 15)) {\n      throw new FormatError(`Unsupported predictor: ${predictor}`);\n    }\n    this.readBlock = predictor === 2 ? this.readBlockTiff : this.readBlockPng;\n    this.str = str;\n    this.dict = str.dict;\n    const colors = this.colors = params.get(\"Colors\") || 1;\n    const bits = this.bits = params.get(\"BPC\", \"BitsPerComponent\") || 8;\n    const columns = this.columns = params.get(\"Columns\") || 1;\n    this.pixBytes = colors * bits + 7 >> 3;\n    this.rowBytes = columns * colors * bits + 7 >> 3;\n    return this;\n  }\n  readBlockTiff() {\n    const rowBytes = this.rowBytes;\n    const bufferLength = this.bufferLength;\n    const buffer = this.ensureBuffer(bufferLength + rowBytes);\n    const bits = this.bits;\n    const colors = this.colors;\n    const rawBytes = this.str.getBytes(rowBytes);\n    this.eof = !rawBytes.length;\n    if (this.eof) {\n      return;\n    }\n    let inbuf = 0,\n      outbuf = 0;\n    let inbits = 0,\n      outbits = 0;\n    let pos = bufferLength;\n    let i;\n    if (bits === 1 && colors === 1) {\n      for (i = 0; i < rowBytes; ++i) {\n        let c = rawBytes[i] ^ inbuf;\n        c ^= c >> 1;\n        c ^= c >> 2;\n        c ^= c >> 4;\n        inbuf = (c & 1) << 7;\n        buffer[pos++] = c;\n      }\n    } else if (bits === 8) {\n      for (i = 0; i < colors; ++i) {\n        buffer[pos++] = rawBytes[i];\n      }\n      for (; i < rowBytes; ++i) {\n        buffer[pos] = buffer[pos - colors] + rawBytes[i];\n        pos++;\n      }\n    } else if (bits === 16) {\n      const bytesPerPixel = colors * 2;\n      for (i = 0; i < bytesPerPixel; ++i) {\n        buffer[pos++] = rawBytes[i];\n      }\n      for (; i < rowBytes; i += 2) {\n        const sum = ((rawBytes[i] & 0xff) << 8) + (rawBytes[i + 1] & 0xff) + ((buffer[pos - bytesPerPixel] & 0xff) << 8) + (buffer[pos - bytesPerPixel + 1] & 0xff);\n        buffer[pos++] = sum >> 8 & 0xff;\n        buffer[pos++] = sum & 0xff;\n      }\n    } else {\n      const compArray = new Uint8Array(colors + 1);\n      const bitMask = (1 << bits) - 1;\n      let j = 0,\n        k = bufferLength;\n      const columns = this.columns;\n      for (i = 0; i < columns; ++i) {\n        for (let kk = 0; kk < colors; ++kk) {\n          if (inbits < bits) {\n            inbuf = inbuf << 8 | rawBytes[j++] & 0xff;\n            inbits += 8;\n          }\n          compArray[kk] = compArray[kk] + (inbuf >> inbits - bits) & bitMask;\n          inbits -= bits;\n          outbuf = outbuf << bits | compArray[kk];\n          outbits += bits;\n          if (outbits >= 8) {\n            buffer[k++] = outbuf >> outbits - 8 & 0xff;\n            outbits -= 8;\n          }\n        }\n      }\n      if (outbits > 0) {\n        buffer[k++] = (outbuf << 8 - outbits) + (inbuf & (1 << 8 - outbits) - 1);\n      }\n    }\n    this.bufferLength += rowBytes;\n  }\n  readBlockPng() {\n    const rowBytes = this.rowBytes;\n    const pixBytes = this.pixBytes;\n    const predictor = this.str.getByte();\n    const rawBytes = this.str.getBytes(rowBytes);\n    this.eof = !rawBytes.length;\n    if (this.eof) {\n      return;\n    }\n    const bufferLength = this.bufferLength;\n    const buffer = this.ensureBuffer(bufferLength + rowBytes);\n    let prevRow = buffer.subarray(bufferLength - rowBytes, bufferLength);\n    if (prevRow.length === 0) {\n      prevRow = new Uint8Array(rowBytes);\n    }\n    let i,\n      j = bufferLength,\n      up,\n      c;\n    switch (predictor) {\n      case 0:\n        for (i = 0; i < rowBytes; ++i) {\n          buffer[j++] = rawBytes[i];\n        }\n        break;\n      case 1:\n        for (i = 0; i < pixBytes; ++i) {\n          buffer[j++] = rawBytes[i];\n        }\n        for (; i < rowBytes; ++i) {\n          buffer[j] = buffer[j - pixBytes] + rawBytes[i] & 0xff;\n          j++;\n        }\n        break;\n      case 2:\n        for (i = 0; i < rowBytes; ++i) {\n          buffer[j++] = prevRow[i] + rawBytes[i] & 0xff;\n        }\n        break;\n      case 3:\n        for (i = 0; i < pixBytes; ++i) {\n          buffer[j++] = (prevRow[i] >> 1) + rawBytes[i];\n        }\n        for (; i < rowBytes; ++i) {\n          buffer[j] = (prevRow[i] + buffer[j - pixBytes] >> 1) + rawBytes[i] & 0xff;\n          j++;\n        }\n        break;\n      case 4:\n        for (i = 0; i < pixBytes; ++i) {\n          up = prevRow[i];\n          c = rawBytes[i];\n          buffer[j++] = up + c;\n        }\n        for (; i < rowBytes; ++i) {\n          up = prevRow[i];\n          const upLeft = prevRow[i - pixBytes];\n          const left = buffer[j - pixBytes];\n          const p = left + up - upLeft;\n          let pa = p - left;\n          if (pa < 0) {\n            pa = -pa;\n          }\n          let pb = p - up;\n          if (pb < 0) {\n            pb = -pb;\n          }\n          let pc = p - upLeft;\n          if (pc < 0) {\n            pc = -pc;\n          }\n          c = rawBytes[i];\n          if (pa <= pb && pa <= pc) {\n            buffer[j++] = left + c;\n          } else if (pb <= pc) {\n            buffer[j++] = up + c;\n          } else {\n            buffer[j++] = upLeft + c;\n          }\n        }\n        break;\n      default:\n        throw new FormatError(`Unsupported predictor: ${predictor}`);\n    }\n    this.bufferLength += rowBytes;\n  }\n}\n\n;// ./src/core/run_length_stream.js\n\nclass RunLengthStream extends DecodeStream {\n  constructor(str, maybeLength) {\n    super(maybeLength);\n    this.str = str;\n    this.dict = str.dict;\n  }\n  readBlock() {\n    const repeatHeader = this.str.getBytes(2);\n    if (!repeatHeader || repeatHeader.length < 2 || repeatHeader[0] === 128) {\n      this.eof = true;\n      return;\n    }\n    let buffer;\n    let bufferLength = this.bufferLength;\n    let n = repeatHeader[0];\n    if (n < 128) {\n      buffer = this.ensureBuffer(bufferLength + n + 1);\n      buffer[bufferLength++] = repeatHeader[1];\n      if (n > 0) {\n        const source = this.str.getBytes(n);\n        buffer.set(source, bufferLength);\n        bufferLength += n;\n      }\n    } else {\n      n = 257 - n;\n      const b = repeatHeader[1];\n      buffer = this.ensureBuffer(bufferLength + n + 1);\n      for (let i = 0; i < n; i++) {\n        buffer[bufferLength++] = b;\n      }\n    }\n    this.bufferLength = bufferLength;\n  }\n}\n\n;// ./src/core/parser.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst MAX_LENGTH_TO_CACHE = 1000;\nfunction getInlineImageCacheKey(bytes) {\n  const strBuf = [],\n    ii = bytes.length;\n  let i = 0;\n  while (i < ii - 1) {\n    strBuf.push(bytes[i++] << 8 | bytes[i++]);\n  }\n  if (i < ii) {\n    strBuf.push(bytes[i]);\n  }\n  return ii + \"_\" + String.fromCharCode.apply(null, strBuf);\n}\nclass Parser {\n  constructor({\n    lexer,\n    xref,\n    allowStreams = false,\n    recoveryMode = false\n  }) {\n    this.lexer = lexer;\n    this.xref = xref;\n    this.allowStreams = allowStreams;\n    this.recoveryMode = recoveryMode;\n    this.imageCache = Object.create(null);\n    this._imageId = 0;\n    this.refill();\n  }\n  refill() {\n    this.buf1 = this.lexer.getObj();\n    this.buf2 = this.lexer.getObj();\n  }\n  shift() {\n    if (this.buf2 instanceof Cmd && this.buf2.cmd === \"ID\") {\n      this.buf1 = this.buf2;\n      this.buf2 = null;\n    } else {\n      this.buf1 = this.buf2;\n      this.buf2 = this.lexer.getObj();\n    }\n  }\n  tryShift() {\n    try {\n      this.shift();\n      return true;\n    } catch (e) {\n      if (e instanceof MissingDataException) {\n        throw e;\n      }\n      return false;\n    }\n  }\n  getObj(cipherTransform = null) {\n    const buf1 = this.buf1;\n    this.shift();\n    if (buf1 instanceof Cmd) {\n      switch (buf1.cmd) {\n        case \"BI\":\n          return this.makeInlineImage(cipherTransform);\n        case \"[\":\n          const array = [];\n          while (!isCmd(this.buf1, \"]\") && this.buf1 !== EOF) {\n            array.push(this.getObj(cipherTransform));\n          }\n          if (this.buf1 === EOF) {\n            if (this.recoveryMode) {\n              return array;\n            }\n            throw new ParserEOFException(\"End of file inside array.\");\n          }\n          this.shift();\n          return array;\n        case \"<<\":\n          const dict = new Dict(this.xref);\n          while (!isCmd(this.buf1, \">>\") && this.buf1 !== EOF) {\n            if (!(this.buf1 instanceof Name)) {\n              info(\"Malformed dictionary: key must be a name object\");\n              this.shift();\n              continue;\n            }\n            const key = this.buf1.name;\n            this.shift();\n            if (this.buf1 === EOF) {\n              break;\n            }\n            dict.set(key, this.getObj(cipherTransform));\n          }\n          if (this.buf1 === EOF) {\n            if (this.recoveryMode) {\n              return dict;\n            }\n            throw new ParserEOFException(\"End of file inside dictionary.\");\n          }\n          if (isCmd(this.buf2, \"stream\")) {\n            return this.allowStreams ? this.makeStream(dict, cipherTransform) : dict;\n          }\n          this.shift();\n          return dict;\n        default:\n          return buf1;\n      }\n    }\n    if (Number.isInteger(buf1)) {\n      if (Number.isInteger(this.buf1) && isCmd(this.buf2, \"R\")) {\n        const ref = Ref.get(buf1, this.buf1);\n        this.shift();\n        this.shift();\n        return ref;\n      }\n      return buf1;\n    }\n    if (typeof buf1 === \"string\") {\n      if (cipherTransform) {\n        return cipherTransform.decryptString(buf1);\n      }\n      return buf1;\n    }\n    return buf1;\n  }\n  findDefaultInlineStreamEnd(stream) {\n    const E = 0x45,\n      I = 0x49,\n      SPACE = 0x20,\n      LF = 0xa,\n      CR = 0xd,\n      NUL = 0x0;\n    const {\n        knownCommands\n      } = this.lexer,\n      startPos = stream.pos,\n      n = 15;\n    let state = 0,\n      ch,\n      maybeEIPos;\n    while ((ch = stream.getByte()) !== -1) {\n      if (state === 0) {\n        state = ch === E ? 1 : 0;\n      } else if (state === 1) {\n        state = ch === I ? 2 : 0;\n      } else {\n        if (ch === SPACE || ch === LF || ch === CR) {\n          maybeEIPos = stream.pos;\n          const followingBytes = stream.peekBytes(n);\n          const ii = followingBytes.length;\n          if (ii === 0) {\n            break;\n          }\n          for (let i = 0; i < ii; i++) {\n            ch = followingBytes[i];\n            if (ch === NUL && followingBytes[i + 1] !== NUL) {\n              continue;\n            }\n            if (ch !== LF && ch !== CR && (ch < SPACE || ch > 0x7f)) {\n              state = 0;\n              break;\n            }\n          }\n          if (state !== 2) {\n            continue;\n          }\n          if (!knownCommands) {\n            warn(\"findDefaultInlineStreamEnd - `lexer.knownCommands` is undefined.\");\n            continue;\n          }\n          const tmpLexer = new Lexer(new Stream(followingBytes.slice()), knownCommands);\n          tmpLexer._hexStringWarn = () => {};\n          let numArgs = 0;\n          while (true) {\n            const nextObj = tmpLexer.getObj();\n            if (nextObj === EOF) {\n              state = 0;\n              break;\n            }\n            if (nextObj instanceof Cmd) {\n              const knownCommand = knownCommands[nextObj.cmd];\n              if (!knownCommand) {\n                state = 0;\n                break;\n              } else if (knownCommand.variableArgs ? numArgs <= knownCommand.numArgs : numArgs === knownCommand.numArgs) {\n                break;\n              }\n              numArgs = 0;\n              continue;\n            }\n            numArgs++;\n          }\n          if (state === 2) {\n            break;\n          }\n        } else {\n          state = 0;\n        }\n      }\n    }\n    if (ch === -1) {\n      warn(\"findDefaultInlineStreamEnd: \" + \"Reached the end of the stream without finding a valid EI marker\");\n      if (maybeEIPos) {\n        warn('... trying to recover by using the last \"EI\" occurrence.');\n        stream.skip(-(stream.pos - maybeEIPos));\n      }\n    }\n    let endOffset = 4;\n    stream.skip(-endOffset);\n    ch = stream.peekByte();\n    stream.skip(endOffset);\n    if (!isWhiteSpace(ch)) {\n      endOffset--;\n    }\n    return stream.pos - endOffset - startPos;\n  }\n  findDCTDecodeInlineStreamEnd(stream) {\n    const startPos = stream.pos;\n    let foundEOI = false,\n      b,\n      markerLength;\n    while ((b = stream.getByte()) !== -1) {\n      if (b !== 0xff) {\n        continue;\n      }\n      switch (stream.getByte()) {\n        case 0x00:\n          break;\n        case 0xff:\n          stream.skip(-1);\n          break;\n        case 0xd9:\n          foundEOI = true;\n          break;\n        case 0xc0:\n        case 0xc1:\n        case 0xc2:\n        case 0xc3:\n        case 0xc5:\n        case 0xc6:\n        case 0xc7:\n        case 0xc9:\n        case 0xca:\n        case 0xcb:\n        case 0xcd:\n        case 0xce:\n        case 0xcf:\n        case 0xc4:\n        case 0xcc:\n        case 0xda:\n        case 0xdb:\n        case 0xdc:\n        case 0xdd:\n        case 0xde:\n        case 0xdf:\n        case 0xe0:\n        case 0xe1:\n        case 0xe2:\n        case 0xe3:\n        case 0xe4:\n        case 0xe5:\n        case 0xe6:\n        case 0xe7:\n        case 0xe8:\n        case 0xe9:\n        case 0xea:\n        case 0xeb:\n        case 0xec:\n        case 0xed:\n        case 0xee:\n        case 0xef:\n        case 0xfe:\n          markerLength = stream.getUint16();\n          if (markerLength > 2) {\n            stream.skip(markerLength - 2);\n          } else {\n            stream.skip(-2);\n          }\n          break;\n      }\n      if (foundEOI) {\n        break;\n      }\n    }\n    const length = stream.pos - startPos;\n    if (b === -1) {\n      warn(\"Inline DCTDecode image stream: \" + \"EOI marker not found, searching for /EI/ instead.\");\n      stream.skip(-length);\n      return this.findDefaultInlineStreamEnd(stream);\n    }\n    this.inlineStreamSkipEI(stream);\n    return length;\n  }\n  findASCII85DecodeInlineStreamEnd(stream) {\n    const TILDE = 0x7e,\n      GT = 0x3e;\n    const startPos = stream.pos;\n    let ch;\n    while ((ch = stream.getByte()) !== -1) {\n      if (ch === TILDE) {\n        const tildePos = stream.pos;\n        ch = stream.peekByte();\n        while (isWhiteSpace(ch)) {\n          stream.skip();\n          ch = stream.peekByte();\n        }\n        if (ch === GT) {\n          stream.skip();\n          break;\n        }\n        if (stream.pos > tildePos) {\n          const maybeEI = stream.peekBytes(2);\n          if (maybeEI[0] === 0x45 && maybeEI[1] === 0x49) {\n            break;\n          }\n        }\n      }\n    }\n    const length = stream.pos - startPos;\n    if (ch === -1) {\n      warn(\"Inline ASCII85Decode image stream: \" + \"EOD marker not found, searching for /EI/ instead.\");\n      stream.skip(-length);\n      return this.findDefaultInlineStreamEnd(stream);\n    }\n    this.inlineStreamSkipEI(stream);\n    return length;\n  }\n  findASCIIHexDecodeInlineStreamEnd(stream) {\n    const GT = 0x3e;\n    const startPos = stream.pos;\n    let ch;\n    while ((ch = stream.getByte()) !== -1) {\n      if (ch === GT) {\n        break;\n      }\n    }\n    const length = stream.pos - startPos;\n    if (ch === -1) {\n      warn(\"Inline ASCIIHexDecode image stream: \" + \"EOD marker not found, searching for /EI/ instead.\");\n      stream.skip(-length);\n      return this.findDefaultInlineStreamEnd(stream);\n    }\n    this.inlineStreamSkipEI(stream);\n    return length;\n  }\n  inlineStreamSkipEI(stream) {\n    const E = 0x45,\n      I = 0x49;\n    let state = 0,\n      ch;\n    while ((ch = stream.getByte()) !== -1) {\n      if (state === 0) {\n        state = ch === E ? 1 : 0;\n      } else if (state === 1) {\n        state = ch === I ? 2 : 0;\n      } else if (state === 2) {\n        break;\n      }\n    }\n  }\n  makeInlineImage(cipherTransform) {\n    const lexer = this.lexer;\n    const stream = lexer.stream;\n    const dictMap = Object.create(null);\n    let dictLength;\n    while (!isCmd(this.buf1, \"ID\") && this.buf1 !== EOF) {\n      if (!(this.buf1 instanceof Name)) {\n        throw new FormatError(\"Dictionary key must be a name object\");\n      }\n      const key = this.buf1.name;\n      this.shift();\n      if (this.buf1 === EOF) {\n        break;\n      }\n      dictMap[key] = this.getObj(cipherTransform);\n    }\n    if (lexer.beginInlineImagePos !== -1) {\n      dictLength = stream.pos - lexer.beginInlineImagePos;\n    }\n    const filter = this.xref.fetchIfRef(dictMap.F || dictMap.Filter);\n    let filterName;\n    if (filter instanceof Name) {\n      filterName = filter.name;\n    } else if (Array.isArray(filter)) {\n      const filterZero = this.xref.fetchIfRef(filter[0]);\n      if (filterZero instanceof Name) {\n        filterName = filterZero.name;\n      }\n    }\n    const startPos = stream.pos;\n    let length;\n    switch (filterName) {\n      case \"DCT\":\n      case \"DCTDecode\":\n        length = this.findDCTDecodeInlineStreamEnd(stream);\n        break;\n      case \"A85\":\n      case \"ASCII85Decode\":\n        length = this.findASCII85DecodeInlineStreamEnd(stream);\n        break;\n      case \"AHx\":\n      case \"ASCIIHexDecode\":\n        length = this.findASCIIHexDecodeInlineStreamEnd(stream);\n        break;\n      default:\n        length = this.findDefaultInlineStreamEnd(stream);\n    }\n    let cacheKey;\n    if (length < MAX_LENGTH_TO_CACHE && dictLength > 0) {\n      const initialStreamPos = stream.pos;\n      stream.pos = lexer.beginInlineImagePos;\n      cacheKey = getInlineImageCacheKey(stream.getBytes(dictLength + length));\n      stream.pos = initialStreamPos;\n      const cacheEntry = this.imageCache[cacheKey];\n      if (cacheEntry !== undefined) {\n        this.buf2 = Cmd.get(\"EI\");\n        this.shift();\n        cacheEntry.reset();\n        return cacheEntry;\n      }\n    }\n    const dict = new Dict(this.xref);\n    for (const key in dictMap) {\n      dict.set(key, dictMap[key]);\n    }\n    let imageStream = stream.makeSubStream(startPos, length, dict);\n    if (cipherTransform) {\n      imageStream = cipherTransform.createStream(imageStream, length);\n    }\n    imageStream = this.filter(imageStream, dict, length);\n    imageStream.dict = dict;\n    if (cacheKey !== undefined) {\n      imageStream.cacheKey = `inline_img_${++this._imageId}`;\n      this.imageCache[cacheKey] = imageStream;\n    }\n    this.buf2 = Cmd.get(\"EI\");\n    this.shift();\n    return imageStream;\n  }\n  _findStreamLength(startPos, signature) {\n    const {\n      stream\n    } = this.lexer;\n    stream.pos = startPos;\n    const SCAN_BLOCK_LENGTH = 2048;\n    const signatureLength = signature.length;\n    while (stream.pos < stream.end) {\n      const scanBytes = stream.peekBytes(SCAN_BLOCK_LENGTH);\n      const scanLength = scanBytes.length - signatureLength;\n      if (scanLength <= 0) {\n        break;\n      }\n      let pos = 0;\n      while (pos < scanLength) {\n        let j = 0;\n        while (j < signatureLength && scanBytes[pos + j] === signature[j]) {\n          j++;\n        }\n        if (j >= signatureLength) {\n          stream.pos += pos;\n          return stream.pos - startPos;\n        }\n        pos++;\n      }\n      stream.pos += scanLength;\n    }\n    return -1;\n  }\n  makeStream(dict, cipherTransform) {\n    const lexer = this.lexer;\n    let stream = lexer.stream;\n    lexer.skipToNextLine();\n    const startPos = stream.pos - 1;\n    let length = dict.get(\"Length\");\n    if (!Number.isInteger(length)) {\n      info(`Bad length \"${length && length.toString()}\" in stream.`);\n      length = 0;\n    }\n    stream.pos = startPos + length;\n    lexer.nextChar();\n    if (this.tryShift() && isCmd(this.buf2, \"endstream\")) {\n      this.shift();\n    } else {\n      const ENDSTREAM_SIGNATURE = new Uint8Array([0x65, 0x6e, 0x64, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d]);\n      let actualLength = this._findStreamLength(startPos, ENDSTREAM_SIGNATURE);\n      if (actualLength < 0) {\n        const MAX_TRUNCATION = 1;\n        for (let i = 1; i <= MAX_TRUNCATION; i++) {\n          const end = ENDSTREAM_SIGNATURE.length - i;\n          const TRUNCATED_SIGNATURE = ENDSTREAM_SIGNATURE.slice(0, end);\n          const maybeLength = this._findStreamLength(startPos, TRUNCATED_SIGNATURE);\n          if (maybeLength >= 0) {\n            const lastByte = stream.peekBytes(end + 1)[end];\n            if (!isWhiteSpace(lastByte)) {\n              break;\n            }\n            info(`Found \"${bytesToString(TRUNCATED_SIGNATURE)}\" when ` + \"searching for endstream command.\");\n            actualLength = maybeLength;\n            break;\n          }\n        }\n        if (actualLength < 0) {\n          throw new FormatError(\"Missing endstream command.\");\n        }\n      }\n      length = actualLength;\n      lexer.nextChar();\n      this.shift();\n      this.shift();\n    }\n    this.shift();\n    stream = stream.makeSubStream(startPos, length, dict);\n    if (cipherTransform) {\n      stream = cipherTransform.createStream(stream, length);\n    }\n    stream = this.filter(stream, dict, length);\n    stream.dict = dict;\n    return stream;\n  }\n  filter(stream, dict, length) {\n    let filter = dict.get(\"F\", \"Filter\");\n    let params = dict.get(\"DP\", \"DecodeParms\");\n    if (filter instanceof Name) {\n      if (Array.isArray(params)) {\n        warn(\"/DecodeParms should not be an Array, when /Filter is a Name.\");\n      }\n      return this.makeFilter(stream, filter.name, length, params);\n    }\n    let maybeLength = length;\n    if (Array.isArray(filter)) {\n      const filterArray = filter;\n      const paramsArray = params;\n      for (let i = 0, ii = filterArray.length; i < ii; ++i) {\n        filter = this.xref.fetchIfRef(filterArray[i]);\n        if (!(filter instanceof Name)) {\n          throw new FormatError(`Bad filter name \"${filter}\"`);\n        }\n        params = null;\n        if (Array.isArray(paramsArray) && i in paramsArray) {\n          params = this.xref.fetchIfRef(paramsArray[i]);\n        }\n        stream = this.makeFilter(stream, filter.name, maybeLength, params);\n        maybeLength = null;\n      }\n    }\n    return stream;\n  }\n  makeFilter(stream, name, maybeLength, params) {\n    if (maybeLength === 0) {\n      warn(`Empty \"${name}\" stream.`);\n      return new NullStream();\n    }\n    try {\n      switch (name) {\n        case \"Fl\":\n        case \"FlateDecode\":\n          if (params) {\n            return new PredictorStream(new FlateStream(stream, maybeLength), maybeLength, params);\n          }\n          return new FlateStream(stream, maybeLength);\n        case \"LZW\":\n        case \"LZWDecode\":\n          let earlyChange = 1;\n          if (params) {\n            if (params.has(\"EarlyChange\")) {\n              earlyChange = params.get(\"EarlyChange\");\n            }\n            return new PredictorStream(new LZWStream(stream, maybeLength, earlyChange), maybeLength, params);\n          }\n          return new LZWStream(stream, maybeLength, earlyChange);\n        case \"DCT\":\n        case \"DCTDecode\":\n          return new JpegStream(stream, maybeLength, params);\n        case \"JPX\":\n        case \"JPXDecode\":\n          return new JpxStream(stream, maybeLength, params);\n        case \"A85\":\n        case \"ASCII85Decode\":\n          return new Ascii85Stream(stream, maybeLength);\n        case \"AHx\":\n        case \"ASCIIHexDecode\":\n          return new AsciiHexStream(stream, maybeLength);\n        case \"CCF\":\n        case \"CCITTFaxDecode\":\n          return new CCITTFaxStream(stream, maybeLength, params);\n        case \"RL\":\n        case \"RunLengthDecode\":\n          return new RunLengthStream(stream, maybeLength);\n        case \"JBIG2Decode\":\n          return new Jbig2Stream(stream, maybeLength, params);\n      }\n      warn(`Filter \"${name}\" is not supported.`);\n      return stream;\n    } catch (ex) {\n      if (ex instanceof MissingDataException) {\n        throw ex;\n      }\n      warn(`Invalid stream: \"${ex}\"`);\n      return new NullStream();\n    }\n  }\n}\nconst specialChars = [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\nfunction toHexDigit(ch) {\n  if (ch >= 0x30 && ch <= 0x39) {\n    return ch & 0x0f;\n  }\n  if (ch >= 0x41 && ch <= 0x46 || ch >= 0x61 && ch <= 0x66) {\n    return (ch & 0x0f) + 9;\n  }\n  return -1;\n}\nclass Lexer {\n  constructor(stream, knownCommands = null) {\n    this.stream = stream;\n    this.nextChar();\n    this.strBuf = [];\n    this.knownCommands = knownCommands;\n    this._hexStringNumWarn = 0;\n    this.beginInlineImagePos = -1;\n  }\n  nextChar() {\n    return this.currentChar = this.stream.getByte();\n  }\n  peekChar() {\n    return this.stream.peekByte();\n  }\n  getNumber() {\n    let ch = this.currentChar;\n    let eNotation = false;\n    let divideBy = 0;\n    let sign = 1;\n    if (ch === 0x2d) {\n      sign = -1;\n      ch = this.nextChar();\n      if (ch === 0x2d) {\n        ch = this.nextChar();\n      }\n    } else if (ch === 0x2b) {\n      ch = this.nextChar();\n    }\n    if (ch === 0x0a || ch === 0x0d) {\n      do {\n        ch = this.nextChar();\n      } while (ch === 0x0a || ch === 0x0d);\n    }\n    if (ch === 0x2e) {\n      divideBy = 10;\n      ch = this.nextChar();\n    }\n    if (ch < 0x30 || ch > 0x39) {\n      const msg = `Invalid number: ${String.fromCharCode(ch)} (charCode ${ch})`;\n      if (isWhiteSpace(ch) || ch === -1) {\n        info(`Lexer.getNumber - \"${msg}\".`);\n        return 0;\n      }\n      throw new FormatError(msg);\n    }\n    let baseValue = ch - 0x30;\n    let powerValue = 0;\n    let powerValueSign = 1;\n    while ((ch = this.nextChar()) >= 0) {\n      if (ch >= 0x30 && ch <= 0x39) {\n        const currentDigit = ch - 0x30;\n        if (eNotation) {\n          powerValue = powerValue * 10 + currentDigit;\n        } else {\n          if (divideBy !== 0) {\n            divideBy *= 10;\n          }\n          baseValue = baseValue * 10 + currentDigit;\n        }\n      } else if (ch === 0x2e) {\n        if (divideBy === 0) {\n          divideBy = 1;\n        } else {\n          break;\n        }\n      } else if (ch === 0x2d) {\n        warn(\"Badly formatted number: minus sign in the middle\");\n      } else if (ch === 0x45 || ch === 0x65) {\n        ch = this.peekChar();\n        if (ch === 0x2b || ch === 0x2d) {\n          powerValueSign = ch === 0x2d ? -1 : 1;\n          this.nextChar();\n        } else if (ch < 0x30 || ch > 0x39) {\n          break;\n        }\n        eNotation = true;\n      } else {\n        break;\n      }\n    }\n    if (divideBy !== 0) {\n      baseValue /= divideBy;\n    }\n    if (eNotation) {\n      baseValue *= 10 ** (powerValueSign * powerValue);\n    }\n    return sign * baseValue;\n  }\n  getString() {\n    let numParen = 1;\n    let done = false;\n    const strBuf = this.strBuf;\n    strBuf.length = 0;\n    let ch = this.nextChar();\n    while (true) {\n      let charBuffered = false;\n      switch (ch | 0) {\n        case -1:\n          warn(\"Unterminated string\");\n          done = true;\n          break;\n        case 0x28:\n          ++numParen;\n          strBuf.push(\"(\");\n          break;\n        case 0x29:\n          if (--numParen === 0) {\n            this.nextChar();\n            done = true;\n          } else {\n            strBuf.push(\")\");\n          }\n          break;\n        case 0x5c:\n          ch = this.nextChar();\n          switch (ch) {\n            case -1:\n              warn(\"Unterminated string\");\n              done = true;\n              break;\n            case 0x6e:\n              strBuf.push(\"\\n\");\n              break;\n            case 0x72:\n              strBuf.push(\"\\r\");\n              break;\n            case 0x74:\n              strBuf.push(\"\\t\");\n              break;\n            case 0x62:\n              strBuf.push(\"\\b\");\n              break;\n            case 0x66:\n              strBuf.push(\"\\f\");\n              break;\n            case 0x5c:\n            case 0x28:\n            case 0x29:\n              strBuf.push(String.fromCharCode(ch));\n              break;\n            case 0x30:\n            case 0x31:\n            case 0x32:\n            case 0x33:\n            case 0x34:\n            case 0x35:\n            case 0x36:\n            case 0x37:\n              let x = ch & 0x0f;\n              ch = this.nextChar();\n              charBuffered = true;\n              if (ch >= 0x30 && ch <= 0x37) {\n                x = (x << 3) + (ch & 0x0f);\n                ch = this.nextChar();\n                if (ch >= 0x30 && ch <= 0x37) {\n                  charBuffered = false;\n                  x = (x << 3) + (ch & 0x0f);\n                }\n              }\n              strBuf.push(String.fromCharCode(x));\n              break;\n            case 0x0d:\n              if (this.peekChar() === 0x0a) {\n                this.nextChar();\n              }\n              break;\n            case 0x0a:\n              break;\n            default:\n              strBuf.push(String.fromCharCode(ch));\n              break;\n          }\n          break;\n        default:\n          strBuf.push(String.fromCharCode(ch));\n          break;\n      }\n      if (done) {\n        break;\n      }\n      if (!charBuffered) {\n        ch = this.nextChar();\n      }\n    }\n    return strBuf.join(\"\");\n  }\n  getName() {\n    let ch, previousCh;\n    const strBuf = this.strBuf;\n    strBuf.length = 0;\n    while ((ch = this.nextChar()) >= 0 && !specialChars[ch]) {\n      if (ch === 0x23) {\n        ch = this.nextChar();\n        if (specialChars[ch]) {\n          warn(\"Lexer_getName: \" + \"NUMBER SIGN (#) should be followed by a hexadecimal number.\");\n          strBuf.push(\"#\");\n          break;\n        }\n        const x = toHexDigit(ch);\n        if (x !== -1) {\n          previousCh = ch;\n          ch = this.nextChar();\n          const x2 = toHexDigit(ch);\n          if (x2 === -1) {\n            warn(`Lexer_getName: Illegal digit (${String.fromCharCode(ch)}) ` + \"in hexadecimal number.\");\n            strBuf.push(\"#\", String.fromCharCode(previousCh));\n            if (specialChars[ch]) {\n              break;\n            }\n            strBuf.push(String.fromCharCode(ch));\n            continue;\n          }\n          strBuf.push(String.fromCharCode(x << 4 | x2));\n        } else {\n          strBuf.push(\"#\", String.fromCharCode(ch));\n        }\n      } else {\n        strBuf.push(String.fromCharCode(ch));\n      }\n    }\n    if (strBuf.length > 127) {\n      warn(`Name token is longer than allowed by the spec: ${strBuf.length}`);\n    }\n    return Name.get(strBuf.join(\"\"));\n  }\n  _hexStringWarn(ch) {\n    const MAX_HEX_STRING_NUM_WARN = 5;\n    if (this._hexStringNumWarn++ === MAX_HEX_STRING_NUM_WARN) {\n      warn(\"getHexString - ignoring additional invalid characters.\");\n      return;\n    }\n    if (this._hexStringNumWarn > MAX_HEX_STRING_NUM_WARN) {\n      return;\n    }\n    warn(`getHexString - ignoring invalid character: ${ch}`);\n  }\n  getHexString() {\n    const strBuf = this.strBuf;\n    strBuf.length = 0;\n    let ch = this.currentChar;\n    let isFirstHex = true;\n    let firstDigit, secondDigit;\n    this._hexStringNumWarn = 0;\n    while (true) {\n      if (ch < 0) {\n        warn(\"Unterminated hex string\");\n        break;\n      } else if (ch === 0x3e) {\n        this.nextChar();\n        break;\n      } else if (specialChars[ch] === 1) {\n        ch = this.nextChar();\n        continue;\n      } else {\n        if (isFirstHex) {\n          firstDigit = toHexDigit(ch);\n          if (firstDigit === -1) {\n            this._hexStringWarn(ch);\n            ch = this.nextChar();\n            continue;\n          }\n        } else {\n          secondDigit = toHexDigit(ch);\n          if (secondDigit === -1) {\n            this._hexStringWarn(ch);\n            ch = this.nextChar();\n            continue;\n          }\n          strBuf.push(String.fromCharCode(firstDigit << 4 | secondDigit));\n        }\n        isFirstHex = !isFirstHex;\n        ch = this.nextChar();\n      }\n    }\n    return strBuf.join(\"\");\n  }\n  getObj() {\n    let comment = false;\n    let ch = this.currentChar;\n    while (true) {\n      if (ch < 0) {\n        return EOF;\n      }\n      if (comment) {\n        if (ch === 0x0a || ch === 0x0d) {\n          comment = false;\n        }\n      } else if (ch === 0x25) {\n        comment = true;\n      } else if (specialChars[ch] !== 1) {\n        break;\n      }\n      ch = this.nextChar();\n    }\n    switch (ch | 0) {\n      case 0x30:\n      case 0x31:\n      case 0x32:\n      case 0x33:\n      case 0x34:\n      case 0x35:\n      case 0x36:\n      case 0x37:\n      case 0x38:\n      case 0x39:\n      case 0x2b:\n      case 0x2d:\n      case 0x2e:\n        return this.getNumber();\n      case 0x28:\n        return this.getString();\n      case 0x2f:\n        return this.getName();\n      case 0x5b:\n        this.nextChar();\n        return Cmd.get(\"[\");\n      case 0x5d:\n        this.nextChar();\n        return Cmd.get(\"]\");\n      case 0x3c:\n        ch = this.nextChar();\n        if (ch === 0x3c) {\n          this.nextChar();\n          return Cmd.get(\"<<\");\n        }\n        return this.getHexString();\n      case 0x3e:\n        ch = this.nextChar();\n        if (ch === 0x3e) {\n          this.nextChar();\n          return Cmd.get(\">>\");\n        }\n        return Cmd.get(\">\");\n      case 0x7b:\n        this.nextChar();\n        return Cmd.get(\"{\");\n      case 0x7d:\n        this.nextChar();\n        return Cmd.get(\"}\");\n      case 0x29:\n        this.nextChar();\n        throw new FormatError(`Illegal character: ${ch}`);\n    }\n    let str = String.fromCharCode(ch);\n    if (ch < 0x20 || ch > 0x7f) {\n      const nextCh = this.peekChar();\n      if (nextCh >= 0x20 && nextCh <= 0x7f) {\n        this.nextChar();\n        return Cmd.get(str);\n      }\n    }\n    const knownCommands = this.knownCommands;\n    let knownCommandFound = knownCommands?.[str] !== undefined;\n    while ((ch = this.nextChar()) >= 0 && !specialChars[ch]) {\n      const possibleCommand = str + String.fromCharCode(ch);\n      if (knownCommandFound && knownCommands[possibleCommand] === undefined) {\n        break;\n      }\n      if (str.length === 128) {\n        throw new FormatError(`Command token too long: ${str.length}`);\n      }\n      str = possibleCommand;\n      knownCommandFound = knownCommands?.[str] !== undefined;\n    }\n    if (str === \"true\") {\n      return true;\n    }\n    if (str === \"false\") {\n      return false;\n    }\n    if (str === \"null\") {\n      return null;\n    }\n    if (str === \"BI\") {\n      this.beginInlineImagePos = this.stream.pos;\n    }\n    return Cmd.get(str);\n  }\n  skipToNextLine() {\n    let ch = this.currentChar;\n    while (ch >= 0) {\n      if (ch === 0x0d) {\n        ch = this.nextChar();\n        if (ch === 0x0a) {\n          this.nextChar();\n        }\n        break;\n      } else if (ch === 0x0a) {\n        this.nextChar();\n        break;\n      }\n      ch = this.nextChar();\n    }\n  }\n}\nclass Linearization {\n  static create(stream) {\n    function getInt(linDict, name, allowZeroValue = false) {\n      const obj = linDict.get(name);\n      if (Number.isInteger(obj) && (allowZeroValue ? obj >= 0 : obj > 0)) {\n        return obj;\n      }\n      throw new Error(`The \"${name}\" parameter in the linearization ` + \"dictionary is invalid.\");\n    }\n    function getHints(linDict) {\n      const hints = linDict.get(\"H\");\n      let hintsLength;\n      if (Array.isArray(hints) && ((hintsLength = hints.length) === 2 || hintsLength === 4)) {\n        for (let index = 0; index < hintsLength; index++) {\n          const hint = hints[index];\n          if (!(Number.isInteger(hint) && hint > 0)) {\n            throw new Error(`Hint (${index}) in the linearization dictionary is invalid.`);\n          }\n        }\n        return hints;\n      }\n      throw new Error(\"Hint array in the linearization dictionary is invalid.\");\n    }\n    const parser = new Parser({\n      lexer: new Lexer(stream),\n      xref: null\n    });\n    const obj1 = parser.getObj();\n    const obj2 = parser.getObj();\n    const obj3 = parser.getObj();\n    const linDict = parser.getObj();\n    let obj, length;\n    if (!(Number.isInteger(obj1) && Number.isInteger(obj2) && isCmd(obj3, \"obj\") && linDict instanceof Dict && typeof (obj = linDict.get(\"Linearized\")) === \"number\" && obj > 0)) {\n      return null;\n    } else if ((length = getInt(linDict, \"L\")) !== stream.length) {\n      throw new Error('The \"L\" parameter in the linearization dictionary ' + \"does not equal the stream length.\");\n    }\n    return {\n      length,\n      hints: getHints(linDict),\n      objectNumberFirst: getInt(linDict, \"O\"),\n      endFirst: getInt(linDict, \"E\"),\n      numPages: getInt(linDict, \"N\"),\n      mainXRefEntriesOffset: getInt(linDict, \"T\"),\n      pageFirst: linDict.has(\"P\") ? getInt(linDict, \"P\", true) : 0\n    };\n  }\n}\n\n;// ./src/core/cmap.js\n\n\n\n\n\n\n\nconst BUILT_IN_CMAPS = [\"Adobe-GB1-UCS2\", \"Adobe-CNS1-UCS2\", \"Adobe-Japan1-UCS2\", \"Adobe-Korea1-UCS2\", \"78-EUC-H\", \"78-EUC-V\", \"78-H\", \"78-RKSJ-H\", \"78-RKSJ-V\", \"78-V\", \"78ms-RKSJ-H\", \"78ms-RKSJ-V\", \"83pv-RKSJ-H\", \"90ms-RKSJ-H\", \"90ms-RKSJ-V\", \"90msp-RKSJ-H\", \"90msp-RKSJ-V\", \"90pv-RKSJ-H\", \"90pv-RKSJ-V\", \"Add-H\", \"Add-RKSJ-H\", \"Add-RKSJ-V\", \"Add-V\", \"Adobe-CNS1-0\", \"Adobe-CNS1-1\", \"Adobe-CNS1-2\", \"Adobe-CNS1-3\", \"Adobe-CNS1-4\", \"Adobe-CNS1-5\", \"Adobe-CNS1-6\", \"Adobe-GB1-0\", \"Adobe-GB1-1\", \"Adobe-GB1-2\", \"Adobe-GB1-3\", \"Adobe-GB1-4\", \"Adobe-GB1-5\", \"Adobe-Japan1-0\", \"Adobe-Japan1-1\", \"Adobe-Japan1-2\", \"Adobe-Japan1-3\", \"Adobe-Japan1-4\", \"Adobe-Japan1-5\", \"Adobe-Japan1-6\", \"Adobe-Korea1-0\", \"Adobe-Korea1-1\", \"Adobe-Korea1-2\", \"B5-H\", \"B5-V\", \"B5pc-H\", \"B5pc-V\", \"CNS-EUC-H\", \"CNS-EUC-V\", \"CNS1-H\", \"CNS1-V\", \"CNS2-H\", \"CNS2-V\", \"ETHK-B5-H\", \"ETHK-B5-V\", \"ETen-B5-H\", \"ETen-B5-V\", \"ETenms-B5-H\", \"ETenms-B5-V\", \"EUC-H\", \"EUC-V\", \"Ext-H\", \"Ext-RKSJ-H\", \"Ext-RKSJ-V\", \"Ext-V\", \"GB-EUC-H\", \"GB-EUC-V\", \"GB-H\", \"GB-V\", \"GBK-EUC-H\", \"GBK-EUC-V\", \"GBK2K-H\", \"GBK2K-V\", \"GBKp-EUC-H\", \"GBKp-EUC-V\", \"GBT-EUC-H\", \"GBT-EUC-V\", \"GBT-H\", \"GBT-V\", \"GBTpc-EUC-H\", \"GBTpc-EUC-V\", \"GBpc-EUC-H\", \"GBpc-EUC-V\", \"H\", \"HKdla-B5-H\", \"HKdla-B5-V\", \"HKdlb-B5-H\", \"HKdlb-B5-V\", \"HKgccs-B5-H\", \"HKgccs-B5-V\", \"HKm314-B5-H\", \"HKm314-B5-V\", \"HKm471-B5-H\", \"HKm471-B5-V\", \"HKscs-B5-H\", \"HKscs-B5-V\", \"Hankaku\", \"Hiragana\", \"KSC-EUC-H\", \"KSC-EUC-V\", \"KSC-H\", \"KSC-Johab-H\", \"KSC-Johab-V\", \"KSC-V\", \"KSCms-UHC-H\", \"KSCms-UHC-HW-H\", \"KSCms-UHC-HW-V\", \"KSCms-UHC-V\", \"KSCpc-EUC-H\", \"KSCpc-EUC-V\", \"Katakana\", \"NWP-H\", \"NWP-V\", \"RKSJ-H\", \"RKSJ-V\", \"Roman\", \"UniCNS-UCS2-H\", \"UniCNS-UCS2-V\", \"UniCNS-UTF16-H\", \"UniCNS-UTF16-V\", \"UniCNS-UTF32-H\", \"UniCNS-UTF32-V\", \"UniCNS-UTF8-H\", \"UniCNS-UTF8-V\", \"UniGB-UCS2-H\", \"UniGB-UCS2-V\", \"UniGB-UTF16-H\", \"UniGB-UTF16-V\", \"UniGB-UTF32-H\", \"UniGB-UTF32-V\", \"UniGB-UTF8-H\", \"UniGB-UTF8-V\", \"UniJIS-UCS2-H\", \"UniJIS-UCS2-HW-H\", \"UniJIS-UCS2-HW-V\", \"UniJIS-UCS2-V\", \"UniJIS-UTF16-H\", \"UniJIS-UTF16-V\", \"UniJIS-UTF32-H\", \"UniJIS-UTF32-V\", \"UniJIS-UTF8-H\", \"UniJIS-UTF8-V\", \"UniJIS2004-UTF16-H\", \"UniJIS2004-UTF16-V\", \"UniJIS2004-UTF32-H\", \"UniJIS2004-UTF32-V\", \"UniJIS2004-UTF8-H\", \"UniJIS2004-UTF8-V\", \"UniJISPro-UCS2-HW-V\", \"UniJISPro-UCS2-V\", \"UniJISPro-UTF8-V\", \"UniJISX0213-UTF32-H\", \"UniJISX0213-UTF32-V\", \"UniJISX02132004-UTF32-H\", \"UniJISX02132004-UTF32-V\", \"UniKS-UCS2-H\", \"UniKS-UCS2-V\", \"UniKS-UTF16-H\", \"UniKS-UTF16-V\", \"UniKS-UTF32-H\", \"UniKS-UTF32-V\", \"UniKS-UTF8-H\", \"UniKS-UTF8-V\", \"V\", \"WP-Symbol\"];\nconst MAX_MAP_RANGE = 2 ** 24 - 1;\nclass CMap {\n  constructor(builtInCMap = false) {\n    this.codespaceRanges = [[], [], [], []];\n    this.numCodespaceRanges = 0;\n    this._map = [];\n    this.name = \"\";\n    this.vertical = false;\n    this.useCMap = null;\n    this.builtInCMap = builtInCMap;\n  }\n  addCodespaceRange(n, low, high) {\n    this.codespaceRanges[n - 1].push(low, high);\n    this.numCodespaceRanges++;\n  }\n  mapCidRange(low, high, dstLow) {\n    if (high - low > MAX_MAP_RANGE) {\n      throw new Error(\"mapCidRange - ignoring data above MAX_MAP_RANGE.\");\n    }\n    while (low <= high) {\n      this._map[low++] = dstLow++;\n    }\n  }\n  mapBfRange(low, high, dstLow) {\n    if (high - low > MAX_MAP_RANGE) {\n      throw new Error(\"mapBfRange - ignoring data above MAX_MAP_RANGE.\");\n    }\n    const lastByte = dstLow.length - 1;\n    while (low <= high) {\n      this._map[low++] = dstLow;\n      const nextCharCode = dstLow.charCodeAt(lastByte) + 1;\n      if (nextCharCode > 0xff) {\n        dstLow = dstLow.substring(0, lastByte - 1) + String.fromCharCode(dstLow.charCodeAt(lastByte - 1) + 1) + \"\\x00\";\n        continue;\n      }\n      dstLow = dstLow.substring(0, lastByte) + String.fromCharCode(nextCharCode);\n    }\n  }\n  mapBfRangeToArray(low, high, array) {\n    if (high - low > MAX_MAP_RANGE) {\n      throw new Error(\"mapBfRangeToArray - ignoring data above MAX_MAP_RANGE.\");\n    }\n    const ii = array.length;\n    let i = 0;\n    while (low <= high && i < ii) {\n      this._map[low] = array[i++];\n      ++low;\n    }\n  }\n  mapOne(src, dst) {\n    this._map[src] = dst;\n  }\n  lookup(code) {\n    return this._map[code];\n  }\n  contains(code) {\n    return this._map[code] !== undefined;\n  }\n  forEach(callback) {\n    const map = this._map;\n    const length = map.length;\n    if (length <= 0x10000) {\n      for (let i = 0; i < length; i++) {\n        if (map[i] !== undefined) {\n          callback(i, map[i]);\n        }\n      }\n    } else {\n      for (const i in map) {\n        callback(i, map[i]);\n      }\n    }\n  }\n  charCodeOf(value) {\n    const map = this._map;\n    if (map.length <= 0x10000) {\n      return map.indexOf(value);\n    }\n    for (const charCode in map) {\n      if (map[charCode] === value) {\n        return charCode | 0;\n      }\n    }\n    return -1;\n  }\n  getMap() {\n    return this._map;\n  }\n  readCharCode(str, offset, out) {\n    let c = 0;\n    const codespaceRanges = this.codespaceRanges;\n    for (let n = 0, nn = codespaceRanges.length; n < nn; n++) {\n      c = (c << 8 | str.charCodeAt(offset + n)) >>> 0;\n      const codespaceRange = codespaceRanges[n];\n      for (let k = 0, kk = codespaceRange.length; k < kk;) {\n        const low = codespaceRange[k++];\n        const high = codespaceRange[k++];\n        if (c >= low && c <= high) {\n          out.charcode = c;\n          out.length = n + 1;\n          return;\n        }\n      }\n    }\n    out.charcode = 0;\n    out.length = 1;\n  }\n  getCharCodeLength(charCode) {\n    const codespaceRanges = this.codespaceRanges;\n    for (let n = 0, nn = codespaceRanges.length; n < nn; n++) {\n      const codespaceRange = codespaceRanges[n];\n      for (let k = 0, kk = codespaceRange.length; k < kk;) {\n        const low = codespaceRange[k++];\n        const high = codespaceRange[k++];\n        if (charCode >= low && charCode <= high) {\n          return n + 1;\n        }\n      }\n    }\n    return 1;\n  }\n  get length() {\n    return this._map.length;\n  }\n  get isIdentityCMap() {\n    if (!(this.name === \"Identity-H\" || this.name === \"Identity-V\")) {\n      return false;\n    }\n    if (this._map.length !== 0x10000) {\n      return false;\n    }\n    for (let i = 0; i < 0x10000; i++) {\n      if (this._map[i] !== i) {\n        return false;\n      }\n    }\n    return true;\n  }\n}\nclass IdentityCMap extends CMap {\n  constructor(vertical, n) {\n    super();\n    this.vertical = vertical;\n    this.addCodespaceRange(n, 0, 0xffff);\n  }\n  mapCidRange(low, high, dstLow) {\n    unreachable(\"should not call mapCidRange\");\n  }\n  mapBfRange(low, high, dstLow) {\n    unreachable(\"should not call mapBfRange\");\n  }\n  mapBfRangeToArray(low, high, array) {\n    unreachable(\"should not call mapBfRangeToArray\");\n  }\n  mapOne(src, dst) {\n    unreachable(\"should not call mapCidOne\");\n  }\n  lookup(code) {\n    return Number.isInteger(code) && code <= 0xffff ? code : undefined;\n  }\n  contains(code) {\n    return Number.isInteger(code) && code <= 0xffff;\n  }\n  forEach(callback) {\n    for (let i = 0; i <= 0xffff; i++) {\n      callback(i, i);\n    }\n  }\n  charCodeOf(value) {\n    return Number.isInteger(value) && value <= 0xffff ? value : -1;\n  }\n  getMap() {\n    const map = new Array(0x10000);\n    for (let i = 0; i <= 0xffff; i++) {\n      map[i] = i;\n    }\n    return map;\n  }\n  get length() {\n    return 0x10000;\n  }\n  get isIdentityCMap() {\n    unreachable(\"should not access .isIdentityCMap\");\n  }\n}\nfunction strToInt(str) {\n  let a = 0;\n  for (let i = 0; i < str.length; i++) {\n    a = a << 8 | str.charCodeAt(i);\n  }\n  return a >>> 0;\n}\nfunction expectString(obj) {\n  if (typeof obj !== \"string\") {\n    throw new FormatError(\"Malformed CMap: expected string.\");\n  }\n}\nfunction expectInt(obj) {\n  if (!Number.isInteger(obj)) {\n    throw new FormatError(\"Malformed CMap: expected int.\");\n  }\n}\nfunction parseBfChar(cMap, lexer) {\n  while (true) {\n    let obj = lexer.getObj();\n    if (obj === EOF) {\n      break;\n    }\n    if (isCmd(obj, \"endbfchar\")) {\n      return;\n    }\n    expectString(obj);\n    const src = strToInt(obj);\n    obj = lexer.getObj();\n    expectString(obj);\n    const dst = obj;\n    cMap.mapOne(src, dst);\n  }\n}\nfunction parseBfRange(cMap, lexer) {\n  while (true) {\n    let obj = lexer.getObj();\n    if (obj === EOF) {\n      break;\n    }\n    if (isCmd(obj, \"endbfrange\")) {\n      return;\n    }\n    expectString(obj);\n    const low = strToInt(obj);\n    obj = lexer.getObj();\n    expectString(obj);\n    const high = strToInt(obj);\n    obj = lexer.getObj();\n    if (Number.isInteger(obj) || typeof obj === \"string\") {\n      const dstLow = Number.isInteger(obj) ? String.fromCharCode(obj) : obj;\n      cMap.mapBfRange(low, high, dstLow);\n    } else if (isCmd(obj, \"[\")) {\n      obj = lexer.getObj();\n      const array = [];\n      while (!isCmd(obj, \"]\") && obj !== EOF) {\n        array.push(obj);\n        obj = lexer.getObj();\n      }\n      cMap.mapBfRangeToArray(low, high, array);\n    } else {\n      break;\n    }\n  }\n  throw new FormatError(\"Invalid bf range.\");\n}\nfunction parseCidChar(cMap, lexer) {\n  while (true) {\n    let obj = lexer.getObj();\n    if (obj === EOF) {\n      break;\n    }\n    if (isCmd(obj, \"endcidchar\")) {\n      return;\n    }\n    expectString(obj);\n    const src = strToInt(obj);\n    obj = lexer.getObj();\n    expectInt(obj);\n    const dst = obj;\n    cMap.mapOne(src, dst);\n  }\n}\nfunction parseCidRange(cMap, lexer) {\n  while (true) {\n    let obj = lexer.getObj();\n    if (obj === EOF) {\n      break;\n    }\n    if (isCmd(obj, \"endcidrange\")) {\n      return;\n    }\n    expectString(obj);\n    const low = strToInt(obj);\n    obj = lexer.getObj();\n    expectString(obj);\n    const high = strToInt(obj);\n    obj = lexer.getObj();\n    expectInt(obj);\n    const dstLow = obj;\n    cMap.mapCidRange(low, high, dstLow);\n  }\n}\nfunction parseCodespaceRange(cMap, lexer) {\n  while (true) {\n    let obj = lexer.getObj();\n    if (obj === EOF) {\n      break;\n    }\n    if (isCmd(obj, \"endcodespacerange\")) {\n      return;\n    }\n    if (typeof obj !== \"string\") {\n      break;\n    }\n    const low = strToInt(obj);\n    obj = lexer.getObj();\n    if (typeof obj !== \"string\") {\n      break;\n    }\n    const high = strToInt(obj);\n    cMap.addCodespaceRange(obj.length, low, high);\n  }\n  throw new FormatError(\"Invalid codespace range.\");\n}\nfunction parseWMode(cMap, lexer) {\n  const obj = lexer.getObj();\n  if (Number.isInteger(obj)) {\n    cMap.vertical = !!obj;\n  }\n}\nfunction parseCMapName(cMap, lexer) {\n  const obj = lexer.getObj();\n  if (obj instanceof Name) {\n    cMap.name = obj.name;\n  }\n}\nasync function parseCMap(cMap, lexer, fetchBuiltInCMap, useCMap) {\n  let previous, embeddedUseCMap;\n  objLoop: while (true) {\n    try {\n      const obj = lexer.getObj();\n      if (obj === EOF) {\n        break;\n      } else if (obj instanceof Name) {\n        if (obj.name === \"WMode\") {\n          parseWMode(cMap, lexer);\n        } else if (obj.name === \"CMapName\") {\n          parseCMapName(cMap, lexer);\n        }\n        previous = obj;\n      } else if (obj instanceof Cmd) {\n        switch (obj.cmd) {\n          case \"endcmap\":\n            break objLoop;\n          case \"usecmap\":\n            if (previous instanceof Name) {\n              embeddedUseCMap = previous.name;\n            }\n            break;\n          case \"begincodespacerange\":\n            parseCodespaceRange(cMap, lexer);\n            break;\n          case \"beginbfchar\":\n            parseBfChar(cMap, lexer);\n            break;\n          case \"begincidchar\":\n            parseCidChar(cMap, lexer);\n            break;\n          case \"beginbfrange\":\n            parseBfRange(cMap, lexer);\n            break;\n          case \"begincidrange\":\n            parseCidRange(cMap, lexer);\n            break;\n        }\n      }\n    } catch (ex) {\n      if (ex instanceof MissingDataException) {\n        throw ex;\n      }\n      warn(\"Invalid cMap data: \" + ex);\n      continue;\n    }\n  }\n  if (!useCMap && embeddedUseCMap) {\n    useCMap = embeddedUseCMap;\n  }\n  if (useCMap) {\n    return extendCMap(cMap, fetchBuiltInCMap, useCMap);\n  }\n  return cMap;\n}\nasync function extendCMap(cMap, fetchBuiltInCMap, useCMap) {\n  cMap.useCMap = await createBuiltInCMap(useCMap, fetchBuiltInCMap);\n  if (cMap.numCodespaceRanges === 0) {\n    const useCodespaceRanges = cMap.useCMap.codespaceRanges;\n    for (let i = 0; i < useCodespaceRanges.length; i++) {\n      cMap.codespaceRanges[i] = useCodespaceRanges[i].slice();\n    }\n    cMap.numCodespaceRanges = cMap.useCMap.numCodespaceRanges;\n  }\n  cMap.useCMap.forEach(function (key, value) {\n    if (!cMap.contains(key)) {\n      cMap.mapOne(key, cMap.useCMap.lookup(key));\n    }\n  });\n  return cMap;\n}\nasync function createBuiltInCMap(name, fetchBuiltInCMap) {\n  if (name === \"Identity-H\") {\n    return new IdentityCMap(false, 2);\n  } else if (name === \"Identity-V\") {\n    return new IdentityCMap(true, 2);\n  }\n  if (!BUILT_IN_CMAPS.includes(name)) {\n    throw new Error(\"Unknown CMap name: \" + name);\n  }\n  if (!fetchBuiltInCMap) {\n    throw new Error(\"Built-in CMap parameters are not provided.\");\n  }\n  const {\n    cMapData,\n    compressionType\n  } = await fetchBuiltInCMap(name);\n  const cMap = new CMap(true);\n  if (compressionType === CMapCompressionType.BINARY) {\n    return new BinaryCMapReader().process(cMapData, cMap, useCMap => extendCMap(cMap, fetchBuiltInCMap, useCMap));\n  }\n  if (compressionType === CMapCompressionType.NONE) {\n    const lexer = new Lexer(new Stream(cMapData));\n    return parseCMap(cMap, lexer, fetchBuiltInCMap, null);\n  }\n  throw new Error(`Invalid CMap \"compressionType\" value: ${compressionType}`);\n}\nclass CMapFactory {\n  static async create({\n    encoding,\n    fetchBuiltInCMap,\n    useCMap\n  }) {\n    if (encoding instanceof Name) {\n      return createBuiltInCMap(encoding.name, fetchBuiltInCMap);\n    } else if (encoding instanceof BaseStream) {\n      const parsedCMap = await parseCMap(new CMap(), new Lexer(encoding), fetchBuiltInCMap, useCMap);\n      if (parsedCMap.isIdentityCMap) {\n        return createBuiltInCMap(parsedCMap.name, fetchBuiltInCMap);\n      }\n      return parsedCMap;\n    }\n    throw new Error(\"Encoding required.\");\n  }\n}\n\n;// ./src/core/charsets.js\nconst ISOAdobeCharset = [\".notdef\", \"space\", \"exclam\", \"quotedbl\", \"numbersign\", \"dollar\", \"percent\", \"ampersand\", \"quoteright\", \"parenleft\", \"parenright\", \"asterisk\", \"plus\", \"comma\", \"hyphen\", \"period\", \"slash\", \"zero\", \"one\", \"two\", \"three\", \"four\", \"five\", \"six\", \"seven\", \"eight\", \"nine\", \"colon\", \"semicolon\", \"less\", \"equal\", \"greater\", \"question\", \"at\", \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\", \"J\", \"K\", \"L\", \"M\", \"N\", \"O\", \"P\", \"Q\", \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\", \"Y\", \"Z\", \"bracketleft\", \"backslash\", \"bracketright\", \"asciicircum\", \"underscore\", \"quoteleft\", \"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\", \"k\", \"l\", \"m\", \"n\", \"o\", \"p\", \"q\", \"r\", \"s\", \"t\", \"u\", \"v\", \"w\", \"x\", \"y\", \"z\", \"braceleft\", \"bar\", \"braceright\", \"asciitilde\", \"exclamdown\", \"cent\", \"sterling\", \"fraction\", \"yen\", \"florin\", \"section\", \"currency\", \"quotesingle\", \"quotedblleft\", \"guillemotleft\", \"guilsinglleft\", \"guilsinglright\", \"fi\", \"fl\", \"endash\", \"dagger\", \"daggerdbl\", \"periodcentered\", \"paragraph\", \"bullet\", \"quotesinglbase\", \"quotedblbase\", \"quotedblright\", \"guillemotright\", \"ellipsis\", \"perthousand\", \"questiondown\", \"grave\", \"acute\", \"circumflex\", \"tilde\", \"macron\", \"breve\", \"dotaccent\", \"dieresis\", \"ring\", \"cedilla\", \"hungarumlaut\", \"ogonek\", \"caron\", \"emdash\", \"AE\", \"ordfeminine\", \"Lslash\", \"Oslash\", \"OE\", \"ordmasculine\", \"ae\", \"dotlessi\", \"lslash\", \"oslash\", \"oe\", \"germandbls\", \"onesuperior\", \"logicalnot\", \"mu\", \"trademark\", \"Eth\", \"onehalf\", \"plusminus\", \"Thorn\", \"onequarter\", \"divide\", \"brokenbar\", \"degree\", \"thorn\", \"threequarters\", \"twosuperior\", \"registered\", \"minus\", \"eth\", \"multiply\", \"threesuperior\", \"copyright\", \"Aacute\", \"Acircumflex\", \"Adieresis\", \"Agrave\", \"Aring\", \"Atilde\", \"Ccedilla\", \"Eacute\", \"Ecircumflex\", \"Edieresis\", \"Egrave\", \"Iacute\", \"Icircumflex\", \"Idieresis\", \"Igrave\", \"Ntilde\", \"Oacute\", \"Ocircumflex\", \"Odieresis\", \"Ograve\", \"Otilde\", \"Scaron\", \"Uacute\", \"Ucircumflex\", \"Udieresis\", \"Ugrave\", \"Yacute\", \"Ydieresis\", \"Zcaron\", \"aacute\", \"acircumflex\", \"adieresis\", \"agrave\", \"aring\", \"atilde\", \"ccedilla\", \"eacute\", \"ecircumflex\", \"edieresis\", \"egrave\", \"iacute\", \"icircumflex\", \"idieresis\", \"igrave\", \"ntilde\", \"oacute\", \"ocircumflex\", \"odieresis\", \"ograve\", \"otilde\", \"scaron\", \"uacute\", \"ucircumflex\", \"udieresis\", \"ugrave\", \"yacute\", \"ydieresis\", \"zcaron\"];\nconst ExpertCharset = [\".notdef\", \"space\", \"exclamsmall\", \"Hungarumlautsmall\", \"dollaroldstyle\", \"dollarsuperior\", \"ampersandsmall\", \"Acutesmall\", \"parenleftsuperior\", \"parenrightsuperior\", \"twodotenleader\", \"onedotenleader\", \"comma\", \"hyphen\", \"period\", \"fraction\", \"zerooldstyle\", \"oneoldstyle\", \"twooldstyle\", \"threeoldstyle\", \"fouroldstyle\", \"fiveoldstyle\", \"sixoldstyle\", \"sevenoldstyle\", \"eightoldstyle\", \"nineoldstyle\", \"colon\", \"semicolon\", \"commasuperior\", \"threequartersemdash\", \"periodsuperior\", \"questionsmall\", \"asuperior\", \"bsuperior\", \"centsuperior\", \"dsuperior\", \"esuperior\", \"isuperior\", \"lsuperior\", \"msuperior\", \"nsuperior\", \"osuperior\", \"rsuperior\", \"ssuperior\", \"tsuperior\", \"ff\", \"fi\", \"fl\", \"ffi\", \"ffl\", \"parenleftinferior\", \"parenrightinferior\", \"Circumflexsmall\", \"hyphensuperior\", \"Gravesmall\", \"Asmall\", \"Bsmall\", \"Csmall\", \"Dsmall\", \"Esmall\", \"Fsmall\", \"Gsmall\", \"Hsmall\", \"Ismall\", \"Jsmall\", \"Ksmall\", \"Lsmall\", \"Msmall\", \"Nsmall\", \"Osmall\", \"Psmall\", \"Qsmall\", \"Rsmall\", \"Ssmall\", \"Tsmall\", \"Usmall\", \"Vsmall\", \"Wsmall\", \"Xsmall\", \"Ysmall\", \"Zsmall\", \"colonmonetary\", \"onefitted\", \"rupiah\", \"Tildesmall\", \"exclamdownsmall\", \"centoldstyle\", \"Lslashsmall\", \"Scaronsmall\", \"Zcaronsmall\", \"Dieresissmall\", \"Brevesmall\", \"Caronsmall\", \"Dotaccentsmall\", \"Macronsmall\", \"figuredash\", \"hypheninferior\", \"Ogoneksmall\", \"Ringsmall\", \"Cedillasmall\", \"onequarter\", \"onehalf\", \"threequarters\", \"questiondownsmall\", \"oneeighth\", \"threeeighths\", \"fiveeighths\", \"seveneighths\", \"onethird\", \"twothirds\", \"zerosuperior\", \"onesuperior\", \"twosuperior\", \"threesuperior\", \"foursuperior\", \"fivesuperior\", \"sixsuperior\", \"sevensuperior\", \"eightsuperior\", \"ninesuperior\", \"zeroinferior\", \"oneinferior\", \"twoinferior\", \"threeinferior\", \"fourinferior\", \"fiveinferior\", \"sixinferior\", \"seveninferior\", \"eightinferior\", \"nineinferior\", \"centinferior\", \"dollarinferior\", \"periodinferior\", \"commainferior\", \"Agravesmall\", \"Aacutesmall\", \"Acircumflexsmall\", \"Atildesmall\", \"Adieresissmall\", \"Aringsmall\", \"AEsmall\", \"Ccedillasmall\", \"Egravesmall\", \"Eacutesmall\", \"Ecircumflexsmall\", \"Edieresissmall\", \"Igravesmall\", \"Iacutesmall\", \"Icircumflexsmall\", \"Idieresissmall\", \"Ethsmall\", \"Ntildesmall\", \"Ogravesmall\", \"Oacutesmall\", \"Ocircumflexsmall\", \"Otildesmall\", \"Odieresissmall\", \"OEsmall\", \"Oslashsmall\", \"Ugravesmall\", \"Uacutesmall\", \"Ucircumflexsmall\", \"Udieresissmall\", \"Yacutesmall\", \"Thornsmall\", \"Ydieresissmall\"];\nconst ExpertSubsetCharset = [\".notdef\", \"space\", \"dollaroldstyle\", \"dollarsuperior\", \"parenleftsuperior\", \"parenrightsuperior\", \"twodotenleader\", \"onedotenleader\", \"comma\", \"hyphen\", \"period\", \"fraction\", \"zerooldstyle\", \"oneoldstyle\", \"twooldstyle\", \"threeoldstyle\", \"fouroldstyle\", \"fiveoldstyle\", \"sixoldstyle\", \"sevenoldstyle\", \"eightoldstyle\", \"nineoldstyle\", \"colon\", \"semicolon\", \"commasuperior\", \"threequartersemdash\", \"periodsuperior\", \"asuperior\", \"bsuperior\", \"centsuperior\", \"dsuperior\", \"esuperior\", \"isuperior\", \"lsuperior\", \"msuperior\", \"nsuperior\", \"osuperior\", \"rsuperior\", \"ssuperior\", \"tsuperior\", \"ff\", \"fi\", \"fl\", \"ffi\", \"ffl\", \"parenleftinferior\", \"parenrightinferior\", \"hyphensuperior\", \"colonmonetary\", \"onefitted\", \"rupiah\", \"centoldstyle\", \"figuredash\", \"hypheninferior\", \"onequarter\", \"onehalf\", \"threequarters\", \"oneeighth\", \"threeeighths\", \"fiveeighths\", \"seveneighths\", \"onethird\", \"twothirds\", \"zerosuperior\", \"onesuperior\", \"twosuperior\", \"threesuperior\", \"foursuperior\", \"fivesuperior\", \"sixsuperior\", \"sevensuperior\", \"eightsuperior\", \"ninesuperior\", \"zeroinferior\", \"oneinferior\", \"twoinferior\", \"threeinferior\", \"fourinferior\", \"fiveinferior\", \"sixinferior\", \"seveninferior\", \"eightinferior\", \"nineinferior\", \"centinferior\", \"dollarinferior\", \"periodinferior\", \"commainferior\"];\n\n;// ./src/core/encodings.js\nconst ExpertEncoding = [\"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"space\", \"exclamsmall\", \"Hungarumlautsmall\", \"\", \"dollaroldstyle\", \"dollarsuperior\", \"ampersandsmall\", \"Acutesmall\", \"parenleftsuperior\", \"parenrightsuperior\", \"twodotenleader\", \"onedotenleader\", \"comma\", \"hyphen\", \"period\", \"fraction\", \"zerooldstyle\", \"oneoldstyle\", \"twooldstyle\", \"threeoldstyle\", \"fouroldstyle\", \"fiveoldstyle\", \"sixoldstyle\", \"sevenoldstyle\", \"eightoldstyle\", \"nineoldstyle\", \"colon\", \"semicolon\", \"commasuperior\", \"threequartersemdash\", \"periodsuperior\", \"questionsmall\", \"\", \"asuperior\", \"bsuperior\", \"centsuperior\", \"dsuperior\", \"esuperior\", \"\", \"\", \"\", \"isuperior\", \"\", \"\", \"lsuperior\", \"msuperior\", \"nsuperior\", \"osuperior\", \"\", \"\", \"rsuperior\", \"ssuperior\", \"tsuperior\", \"\", \"ff\", \"fi\", \"fl\", \"ffi\", \"ffl\", \"parenleftinferior\", \"\", \"parenrightinferior\", \"Circumflexsmall\", \"hyphensuperior\", \"Gravesmall\", \"Asmall\", \"Bsmall\", \"Csmall\", \"Dsmall\", \"Esmall\", \"Fsmall\", \"Gsmall\", \"Hsmall\", \"Ismall\", \"Jsmall\", \"Ksmall\", \"Lsmall\", \"Msmall\", \"Nsmall\", \"Osmall\", \"Psmall\", \"Qsmall\", \"Rsmall\", \"Ssmall\", \"Tsmall\", \"Usmall\", \"Vsmall\", \"Wsmall\", \"Xsmall\", \"Ysmall\", \"Zsmall\", \"colonmonetary\", \"onefitted\", \"rupiah\", \"Tildesmall\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"exclamdownsmall\", \"centoldstyle\", \"Lslashsmall\", \"\", \"\", \"Scaronsmall\", \"Zcaronsmall\", \"Dieresissmall\", \"Brevesmall\", \"Caronsmall\", \"\", \"Dotaccentsmall\", \"\", \"\", \"Macronsmall\", \"\", \"\", \"figuredash\", \"hypheninferior\", \"\", \"\", \"Ogoneksmall\", \"Ringsmall\", \"Cedillasmall\", \"\", \"\", \"\", \"onequarter\", \"onehalf\", \"threequarters\", \"questiondownsmall\", \"oneeighth\", \"threeeighths\", \"fiveeighths\", \"seveneighths\", \"onethird\", \"twothirds\", \"\", \"\", \"zerosuperior\", \"onesuperior\", \"twosuperior\", \"threesuperior\", \"foursuperior\", \"fivesuperior\", \"sixsuperior\", \"sevensuperior\", \"eightsuperior\", \"ninesuperior\", \"zeroinferior\", \"oneinferior\", \"twoinferior\", \"threeinferior\", \"fourinferior\", \"fiveinferior\", \"sixinferior\", \"seveninferior\", \"eightinferior\", \"nineinferior\", \"centinferior\", \"dollarinferior\", \"periodinferior\", \"commainferior\", \"Agravesmall\", \"Aacutesmall\", \"Acircumflexsmall\", \"Atildesmall\", \"Adieresissmall\", \"Aringsmall\", \"AEsmall\", \"Ccedillasmall\", \"Egravesmall\", \"Eacutesmall\", \"Ecircumflexsmall\", \"Edieresissmall\", \"Igravesmall\", \"Iacutesmall\", \"Icircumflexsmall\", \"Idieresissmall\", \"Ethsmall\", \"Ntildesmall\", \"Ogravesmall\", \"Oacutesmall\", \"Ocircumflexsmall\", \"Otildesmall\", \"Odieresissmall\", \"OEsmall\", \"Oslashsmall\", \"Ugravesmall\", \"Uacutesmall\", \"Ucircumflexsmall\", \"Udieresissmall\", \"Yacutesmall\", \"Thornsmall\", \"Ydieresissmall\"];\nconst MacExpertEncoding = [\"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"space\", \"exclamsmall\", \"Hungarumlautsmall\", \"centoldstyle\", \"dollaroldstyle\", \"dollarsuperior\", \"ampersandsmall\", \"Acutesmall\", \"parenleftsuperior\", \"parenrightsuperior\", \"twodotenleader\", \"onedotenleader\", \"comma\", \"hyphen\", \"period\", \"fraction\", \"zerooldstyle\", \"oneoldstyle\", \"twooldstyle\", \"threeoldstyle\", \"fouroldstyle\", \"fiveoldstyle\", \"sixoldstyle\", \"sevenoldstyle\", \"eightoldstyle\", \"nineoldstyle\", \"colon\", \"semicolon\", \"\", \"threequartersemdash\", \"\", \"questionsmall\", \"\", \"\", \"\", \"\", \"Ethsmall\", \"\", \"\", \"onequarter\", \"onehalf\", \"threequarters\", \"oneeighth\", \"threeeighths\", \"fiveeighths\", \"seveneighths\", \"onethird\", \"twothirds\", \"\", \"\", \"\", \"\", \"\", \"\", \"ff\", \"fi\", \"fl\", \"ffi\", \"ffl\", \"parenleftinferior\", \"\", \"parenrightinferior\", \"Circumflexsmall\", \"hypheninferior\", \"Gravesmall\", \"Asmall\", \"Bsmall\", \"Csmall\", \"Dsmall\", \"Esmall\", \"Fsmall\", \"Gsmall\", \"Hsmall\", \"Ismall\", \"Jsmall\", \"Ksmall\", \"Lsmall\", \"Msmall\", \"Nsmall\", \"Osmall\", \"Psmall\", \"Qsmall\", \"Rsmall\", \"Ssmall\", \"Tsmall\", \"Usmall\", \"Vsmall\", \"Wsmall\", \"Xsmall\", \"Ysmall\", \"Zsmall\", \"colonmonetary\", \"onefitted\", \"rupiah\", \"Tildesmall\", \"\", \"\", \"asuperior\", \"centsuperior\", \"\", \"\", \"\", \"\", \"Aacutesmall\", \"Agravesmall\", \"Acircumflexsmall\", \"Adieresissmall\", \"Atildesmall\", \"Aringsmall\", \"Ccedillasmall\", \"Eacutesmall\", \"Egravesmall\", \"Ecircumflexsmall\", \"Edieresissmall\", \"Iacutesmall\", \"Igravesmall\", \"Icircumflexsmall\", \"Idieresissmall\", \"Ntildesmall\", \"Oacutesmall\", \"Ogravesmall\", \"Ocircumflexsmall\", \"Odieresissmall\", \"Otildesmall\", \"Uacutesmall\", \"Ugravesmall\", \"Ucircumflexsmall\", \"Udieresissmall\", \"\", \"eightsuperior\", \"fourinferior\", \"threeinferior\", \"sixinferior\", \"eightinferior\", \"seveninferior\", \"Scaronsmall\", \"\", \"centinferior\", \"twoinferior\", \"\", \"Dieresissmall\", \"\", \"Caronsmall\", \"osuperior\", \"fiveinferior\", \"\", \"commainferior\", \"periodinferior\", \"Yacutesmall\", \"\", \"dollarinferior\", \"\", \"\", \"Thornsmall\", \"\", \"nineinferior\", \"zeroinferior\", \"Zcaronsmall\", \"AEsmall\", \"Oslashsmall\", \"questiondownsmall\", \"oneinferior\", \"Lslashsmall\", \"\", \"\", \"\", \"\", \"\", \"\", \"Cedillasmall\", \"\", \"\", \"\", \"\", \"\", \"OEsmall\", \"figuredash\", \"hyphensuperior\", \"\", \"\", \"\", \"\", \"exclamdownsmall\", \"\", \"Ydieresissmall\", \"\", \"onesuperior\", \"twosuperior\", \"threesuperior\", \"foursuperior\", \"fivesuperior\", \"sixsuperior\", \"sevensuperior\", \"ninesuperior\", \"zerosuperior\", \"\", \"esuperior\", \"rsuperior\", \"tsuperior\", \"\", \"\", \"isuperior\", \"ssuperior\", \"dsuperior\", \"\", \"\", \"\", \"\", \"\", \"lsuperior\", \"Ogoneksmall\", \"Brevesmall\", \"Macronsmall\", \"bsuperior\", \"nsuperior\", \"msuperior\", \"commasuperior\", \"periodsuperior\", \"Dotaccentsmall\", \"Ringsmall\", \"\", \"\", \"\", \"\"];\nconst MacRomanEncoding = [\"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"space\", \"exclam\", \"quotedbl\", \"numbersign\", \"dollar\", \"percent\", \"ampersand\", \"quotesingle\", \"parenleft\", \"parenright\", \"asterisk\", \"plus\", \"comma\", \"hyphen\", \"period\", \"slash\", \"zero\", \"one\", \"two\", \"three\", \"four\", \"five\", \"six\", \"seven\", \"eight\", \"nine\", \"colon\", \"semicolon\", \"less\", \"equal\", \"greater\", \"question\", \"at\", \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\", \"J\", \"K\", \"L\", \"M\", \"N\", \"O\", \"P\", \"Q\", \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\", \"Y\", \"Z\", \"bracketleft\", \"backslash\", \"bracketright\", \"asciicircum\", \"underscore\", \"grave\", \"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\", \"k\", \"l\", \"m\", \"n\", \"o\", \"p\", \"q\", \"r\", \"s\", \"t\", \"u\", \"v\", \"w\", \"x\", \"y\", \"z\", \"braceleft\", \"bar\", \"braceright\", \"asciitilde\", \"\", \"Adieresis\", \"Aring\", \"Ccedilla\", \"Eacute\", \"Ntilde\", \"Odieresis\", \"Udieresis\", \"aacute\", \"agrave\", \"acircumflex\", \"adieresis\", \"atilde\", \"aring\", \"ccedilla\", \"eacute\", \"egrave\", \"ecircumflex\", \"edieresis\", \"iacute\", \"igrave\", \"icircumflex\", \"idieresis\", \"ntilde\", \"oacute\", \"ograve\", \"ocircumflex\", \"odieresis\", \"otilde\", \"uacute\", \"ugrave\", \"ucircumflex\", \"udieresis\", \"dagger\", \"degree\", \"cent\", \"sterling\", \"section\", \"bullet\", \"paragraph\", \"germandbls\", \"registered\", \"copyright\", \"trademark\", \"acute\", \"dieresis\", \"notequal\", \"AE\", \"Oslash\", \"infinity\", \"plusminus\", \"lessequal\", \"greaterequal\", \"yen\", \"mu\", \"partialdiff\", \"summation\", \"product\", \"pi\", \"integral\", \"ordfeminine\", \"ordmasculine\", \"Omega\", \"ae\", \"oslash\", \"questiondown\", \"exclamdown\", \"logicalnot\", \"radical\", \"florin\", \"approxequal\", \"Delta\", \"guillemotleft\", \"guillemotright\", \"ellipsis\", \"space\", \"Agrave\", \"Atilde\", \"Otilde\", \"OE\", \"oe\", \"endash\", \"emdash\", \"quotedblleft\", \"quotedblright\", \"quoteleft\", \"quoteright\", \"divide\", \"lozenge\", \"ydieresis\", \"Ydieresis\", \"fraction\", \"currency\", \"guilsinglleft\", \"guilsinglright\", \"fi\", \"fl\", \"daggerdbl\", \"periodcentered\", \"quotesinglbase\", \"quotedblbase\", \"perthousand\", \"Acircumflex\", \"Ecircumflex\", \"Aacute\", \"Edieresis\", \"Egrave\", \"Iacute\", \"Icircumflex\", \"Idieresis\", \"Igrave\", \"Oacute\", \"Ocircumflex\", \"apple\", \"Ograve\", \"Uacute\", \"Ucircumflex\", \"Ugrave\", \"dotlessi\", \"circumflex\", \"tilde\", \"macron\", \"breve\", \"dotaccent\", \"ring\", \"cedilla\", \"hungarumlaut\", \"ogonek\", \"caron\"];\nconst StandardEncoding = [\"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"space\", \"exclam\", \"quotedbl\", \"numbersign\", \"dollar\", \"percent\", \"ampersand\", \"quoteright\", \"parenleft\", \"parenright\", \"asterisk\", \"plus\", \"comma\", \"hyphen\", \"period\", \"slash\", \"zero\", \"one\", \"two\", \"three\", \"four\", \"five\", \"six\", \"seven\", \"eight\", \"nine\", \"colon\", \"semicolon\", \"less\", \"equal\", \"greater\", \"question\", \"at\", \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\", \"J\", \"K\", \"L\", \"M\", \"N\", \"O\", \"P\", \"Q\", \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\", \"Y\", \"Z\", \"bracketleft\", \"backslash\", \"bracketright\", \"asciicircum\", \"underscore\", \"quoteleft\", \"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\", \"k\", \"l\", \"m\", \"n\", \"o\", \"p\", \"q\", \"r\", \"s\", \"t\", \"u\", \"v\", \"w\", \"x\", \"y\", \"z\", \"braceleft\", \"bar\", \"braceright\", \"asciitilde\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"exclamdown\", \"cent\", \"sterling\", \"fraction\", \"yen\", \"florin\", \"section\", \"currency\", \"quotesingle\", \"quotedblleft\", \"guillemotleft\", \"guilsinglleft\", \"guilsinglright\", \"fi\", \"fl\", \"\", \"endash\", \"dagger\", \"daggerdbl\", \"periodcentered\", \"\", \"paragraph\", \"bullet\", \"quotesinglbase\", \"quotedblbase\", \"quotedblright\", \"guillemotright\", \"ellipsis\", \"perthousand\", \"\", \"questiondown\", \"\", \"grave\", \"acute\", \"circumflex\", \"tilde\", \"macron\", \"breve\", \"dotaccent\", \"dieresis\", \"\", \"ring\", \"cedilla\", \"\", \"hungarumlaut\", \"ogonek\", \"caron\", \"emdash\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"AE\", \"\", \"ordfeminine\", \"\", \"\", \"\", \"\", \"Lslash\", \"Oslash\", \"OE\", \"ordmasculine\", \"\", \"\", \"\", \"\", \"\", \"ae\", \"\", \"\", \"\", \"dotlessi\", \"\", \"\", \"lslash\", \"oslash\", \"oe\", \"germandbls\", \"\", \"\", \"\", \"\"];\nconst WinAnsiEncoding = [\"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"space\", \"exclam\", \"quotedbl\", \"numbersign\", \"dollar\", \"percent\", \"ampersand\", \"quotesingle\", \"parenleft\", \"parenright\", \"asterisk\", \"plus\", \"comma\", \"hyphen\", \"period\", \"slash\", \"zero\", \"one\", \"two\", \"three\", \"four\", \"five\", \"six\", \"seven\", \"eight\", \"nine\", \"colon\", \"semicolon\", \"less\", \"equal\", \"greater\", \"question\", \"at\", \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\", \"J\", \"K\", \"L\", \"M\", \"N\", \"O\", \"P\", \"Q\", \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\", \"Y\", \"Z\", \"bracketleft\", \"backslash\", \"bracketright\", \"asciicircum\", \"underscore\", \"grave\", \"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\", \"k\", \"l\", \"m\", \"n\", \"o\", \"p\", \"q\", \"r\", \"s\", \"t\", \"u\", \"v\", \"w\", \"x\", \"y\", \"z\", \"braceleft\", \"bar\", \"braceright\", \"asciitilde\", \"bullet\", \"Euro\", \"bullet\", \"quotesinglbase\", \"florin\", \"quotedblbase\", \"ellipsis\", \"dagger\", \"daggerdbl\", \"circumflex\", \"perthousand\", \"Scaron\", \"guilsinglleft\", \"OE\", \"bullet\", \"Zcaron\", \"bullet\", \"bullet\", \"quoteleft\", \"quoteright\", \"quotedblleft\", \"quotedblright\", \"bullet\", \"endash\", \"emdash\", \"tilde\", \"trademark\", \"scaron\", \"guilsinglright\", \"oe\", \"bullet\", \"zcaron\", \"Ydieresis\", \"space\", \"exclamdown\", \"cent\", \"sterling\", \"currency\", \"yen\", \"brokenbar\", \"section\", \"dieresis\", \"copyright\", \"ordfeminine\", \"guillemotleft\", \"logicalnot\", \"hyphen\", \"registered\", \"macron\", \"degree\", \"plusminus\", \"twosuperior\", \"threesuperior\", \"acute\", \"mu\", \"paragraph\", \"periodcentered\", \"cedilla\", \"onesuperior\", \"ordmasculine\", \"guillemotright\", \"onequarter\", \"onehalf\", \"threequarters\", \"questiondown\", \"Agrave\", \"Aacute\", \"Acircumflex\", \"Atilde\", \"Adieresis\", \"Aring\", \"AE\", \"Ccedilla\", \"Egrave\", \"Eacute\", \"Ecircumflex\", \"Edieresis\", \"Igrave\", \"Iacute\", \"Icircumflex\", \"Idieresis\", \"Eth\", \"Ntilde\", \"Ograve\", \"Oacute\", \"Ocircumflex\", \"Otilde\", \"Odieresis\", \"multiply\", \"Oslash\", \"Ugrave\", \"Uacute\", \"Ucircumflex\", \"Udieresis\", \"Yacute\", \"Thorn\", \"germandbls\", \"agrave\", \"aacute\", \"acircumflex\", \"atilde\", \"adieresis\", \"aring\", \"ae\", \"ccedilla\", \"egrave\", \"eacute\", \"ecircumflex\", \"edieresis\", \"igrave\", \"iacute\", \"icircumflex\", \"idieresis\", \"eth\", \"ntilde\", \"ograve\", \"oacute\", \"ocircumflex\", \"otilde\", \"odieresis\", \"divide\", \"oslash\", \"ugrave\", \"uacute\", \"ucircumflex\", \"udieresis\", \"yacute\", \"thorn\", \"ydieresis\"];\nconst SymbolSetEncoding = [\"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"space\", \"exclam\", \"universal\", \"numbersign\", \"existential\", \"percent\", \"ampersand\", \"suchthat\", \"parenleft\", \"parenright\", \"asteriskmath\", \"plus\", \"comma\", \"minus\", \"period\", \"slash\", \"zero\", \"one\", \"two\", \"three\", \"four\", \"five\", \"six\", \"seven\", \"eight\", \"nine\", \"colon\", \"semicolon\", \"less\", \"equal\", \"greater\", \"question\", \"congruent\", \"Alpha\", \"Beta\", \"Chi\", \"Delta\", \"Epsilon\", \"Phi\", \"Gamma\", \"Eta\", \"Iota\", \"theta1\", \"Kappa\", \"Lambda\", \"Mu\", \"Nu\", \"Omicron\", \"Pi\", \"Theta\", \"Rho\", \"Sigma\", \"Tau\", \"Upsilon\", \"sigma1\", \"Omega\", \"Xi\", \"Psi\", \"Zeta\", \"bracketleft\", \"therefore\", \"bracketright\", \"perpendicular\", \"underscore\", \"radicalex\", \"alpha\", \"beta\", \"chi\", \"delta\", \"epsilon\", \"phi\", \"gamma\", \"eta\", \"iota\", \"phi1\", \"kappa\", \"lambda\", \"mu\", \"nu\", \"omicron\", \"pi\", \"theta\", \"rho\", \"sigma\", \"tau\", \"upsilon\", \"omega1\", \"omega\", \"xi\", \"psi\", \"zeta\", \"braceleft\", \"bar\", \"braceright\", \"similar\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"Euro\", \"Upsilon1\", \"minute\", \"lessequal\", \"fraction\", \"infinity\", \"florin\", \"club\", \"diamond\", \"heart\", \"spade\", \"arrowboth\", \"arrowleft\", \"arrowup\", \"arrowright\", \"arrowdown\", \"degree\", \"plusminus\", \"second\", \"greaterequal\", \"multiply\", \"proportional\", \"partialdiff\", \"bullet\", \"divide\", \"notequal\", \"equivalence\", \"approxequal\", \"ellipsis\", \"arrowvertex\", \"arrowhorizex\", \"carriagereturn\", \"aleph\", \"Ifraktur\", \"Rfraktur\", \"weierstrass\", \"circlemultiply\", \"circleplus\", \"emptyset\", \"intersection\", \"union\", \"propersuperset\", \"reflexsuperset\", \"notsubset\", \"propersubset\", \"reflexsubset\", \"element\", \"notelement\", \"angle\", \"gradient\", \"registerserif\", \"copyrightserif\", \"trademarkserif\", \"product\", \"radical\", \"dotmath\", \"logicalnot\", \"logicaland\", \"logicalor\", \"arrowdblboth\", \"arrowdblleft\", \"arrowdblup\", \"arrowdblright\", \"arrowdbldown\", \"lozenge\", \"angleleft\", \"registersans\", \"copyrightsans\", \"trademarksans\", \"summation\", \"parenlefttp\", \"parenleftex\", \"parenleftbt\", \"bracketlefttp\", \"bracketleftex\", \"bracketleftbt\", \"bracelefttp\", \"braceleftmid\", \"braceleftbt\", \"braceex\", \"\", \"angleright\", \"integral\", \"integraltp\", \"integralex\", \"integralbt\", \"parenrighttp\", \"parenrightex\", \"parenrightbt\", \"bracketrighttp\", \"bracketrightex\", \"bracketrightbt\", \"bracerighttp\", \"bracerightmid\", \"bracerightbt\", \"\"];\nconst ZapfDingbatsEncoding = [\"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"space\", \"a1\", \"a2\", \"a202\", \"a3\", \"a4\", \"a5\", \"a119\", \"a118\", \"a117\", \"a11\", \"a12\", \"a13\", \"a14\", \"a15\", \"a16\", \"a105\", \"a17\", \"a18\", \"a19\", \"a20\", \"a21\", \"a22\", \"a23\", \"a24\", \"a25\", \"a26\", \"a27\", \"a28\", \"a6\", \"a7\", \"a8\", \"a9\", \"a10\", \"a29\", \"a30\", \"a31\", \"a32\", \"a33\", \"a34\", \"a35\", \"a36\", \"a37\", \"a38\", \"a39\", \"a40\", \"a41\", \"a42\", \"a43\", \"a44\", \"a45\", \"a46\", \"a47\", \"a48\", \"a49\", \"a50\", \"a51\", \"a52\", \"a53\", \"a54\", \"a55\", \"a56\", \"a57\", \"a58\", \"a59\", \"a60\", \"a61\", \"a62\", \"a63\", \"a64\", \"a65\", \"a66\", \"a67\", \"a68\", \"a69\", \"a70\", \"a71\", \"a72\", \"a73\", \"a74\", \"a203\", \"a75\", \"a204\", \"a76\", \"a77\", \"a78\", \"a79\", \"a81\", \"a82\", \"a83\", \"a84\", \"a97\", \"a98\", \"a99\", \"a100\", \"\", \"a89\", \"a90\", \"a93\", \"a94\", \"a91\", \"a92\", \"a205\", \"a85\", \"a206\", \"a86\", \"a87\", \"a88\", \"a95\", \"a96\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"a101\", \"a102\", \"a103\", \"a104\", \"a106\", \"a107\", \"a108\", \"a112\", \"a111\", \"a110\", \"a109\", \"a120\", \"a121\", \"a122\", \"a123\", \"a124\", \"a125\", \"a126\", \"a127\", \"a128\", \"a129\", \"a130\", \"a131\", \"a132\", \"a133\", \"a134\", \"a135\", \"a136\", \"a137\", \"a138\", \"a139\", \"a140\", \"a141\", \"a142\", \"a143\", \"a144\", \"a145\", \"a146\", \"a147\", \"a148\", \"a149\", \"a150\", \"a151\", \"a152\", \"a153\", \"a154\", \"a155\", \"a156\", \"a157\", \"a158\", \"a159\", \"a160\", \"a161\", \"a163\", \"a164\", \"a196\", \"a165\", \"a192\", \"a166\", \"a167\", \"a168\", \"a169\", \"a170\", \"a171\", \"a172\", \"a173\", \"a162\", \"a174\", \"a175\", \"a176\", \"a177\", \"a178\", \"a179\", \"a193\", \"a180\", \"a199\", \"a181\", \"a200\", \"a182\", \"\", \"a201\", \"a183\", \"a184\", \"a197\", \"a185\", \"a194\", \"a198\", \"a186\", \"a195\", \"a187\", \"a188\", \"a189\", \"a190\", \"a191\", \"\"];\nfunction getEncoding(encodingName) {\n  switch (encodingName) {\n    case \"WinAnsiEncoding\":\n      return WinAnsiEncoding;\n    case \"StandardEncoding\":\n      return StandardEncoding;\n    case \"MacRomanEncoding\":\n      return MacRomanEncoding;\n    case \"SymbolSetEncoding\":\n      return SymbolSetEncoding;\n    case \"ZapfDingbatsEncoding\":\n      return ZapfDingbatsEncoding;\n    case \"ExpertEncoding\":\n      return ExpertEncoding;\n    case \"MacExpertEncoding\":\n      return MacExpertEncoding;\n    default:\n      return null;\n  }\n}\n\n;// ./src/core/cff_parser.js\n\n\n\nconst MAX_SUBR_NESTING = 10;\nconst CFFStandardStrings = [\".notdef\", \"space\", \"exclam\", \"quotedbl\", \"numbersign\", \"dollar\", \"percent\", \"ampersand\", \"quoteright\", \"parenleft\", \"parenright\", \"asterisk\", \"plus\", \"comma\", \"hyphen\", \"period\", \"slash\", \"zero\", \"one\", \"two\", \"three\", \"four\", \"five\", \"six\", \"seven\", \"eight\", \"nine\", \"colon\", \"semicolon\", \"less\", \"equal\", \"greater\", \"question\", \"at\", \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\", \"J\", \"K\", \"L\", \"M\", \"N\", \"O\", \"P\", \"Q\", \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\", \"Y\", \"Z\", \"bracketleft\", \"backslash\", \"bracketright\", \"asciicircum\", \"underscore\", \"quoteleft\", \"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\", \"k\", \"l\", \"m\", \"n\", \"o\", \"p\", \"q\", \"r\", \"s\", \"t\", \"u\", \"v\", \"w\", \"x\", \"y\", \"z\", \"braceleft\", \"bar\", \"braceright\", \"asciitilde\", \"exclamdown\", \"cent\", \"sterling\", \"fraction\", \"yen\", \"florin\", \"section\", \"currency\", \"quotesingle\", \"quotedblleft\", \"guillemotleft\", \"guilsinglleft\", \"guilsinglright\", \"fi\", \"fl\", \"endash\", \"dagger\", \"daggerdbl\", \"periodcentered\", \"paragraph\", \"bullet\", \"quotesinglbase\", \"quotedblbase\", \"quotedblright\", \"guillemotright\", \"ellipsis\", \"perthousand\", \"questiondown\", \"grave\", \"acute\", \"circumflex\", \"tilde\", \"macron\", \"breve\", \"dotaccent\", \"dieresis\", \"ring\", \"cedilla\", \"hungarumlaut\", \"ogonek\", \"caron\", \"emdash\", \"AE\", \"ordfeminine\", \"Lslash\", \"Oslash\", \"OE\", \"ordmasculine\", \"ae\", \"dotlessi\", \"lslash\", \"oslash\", \"oe\", \"germandbls\", \"onesuperior\", \"logicalnot\", \"mu\", \"trademark\", \"Eth\", \"onehalf\", \"plusminus\", \"Thorn\", \"onequarter\", \"divide\", \"brokenbar\", \"degree\", \"thorn\", \"threequarters\", \"twosuperior\", \"registered\", \"minus\", \"eth\", \"multiply\", \"threesuperior\", \"copyright\", \"Aacute\", \"Acircumflex\", \"Adieresis\", \"Agrave\", \"Aring\", \"Atilde\", \"Ccedilla\", \"Eacute\", \"Ecircumflex\", \"Edieresis\", \"Egrave\", \"Iacute\", \"Icircumflex\", \"Idieresis\", \"Igrave\", \"Ntilde\", \"Oacute\", \"Ocircumflex\", \"Odieresis\", \"Ograve\", \"Otilde\", \"Scaron\", \"Uacute\", \"Ucircumflex\", \"Udieresis\", \"Ugrave\", \"Yacute\", \"Ydieresis\", \"Zcaron\", \"aacute\", \"acircumflex\", \"adieresis\", \"agrave\", \"aring\", \"atilde\", \"ccedilla\", \"eacute\", \"ecircumflex\", \"edieresis\", \"egrave\", \"iacute\", \"icircumflex\", \"idieresis\", \"igrave\", \"ntilde\", \"oacute\", \"ocircumflex\", \"odieresis\", \"ograve\", \"otilde\", \"scaron\", \"uacute\", \"ucircumflex\", \"udieresis\", \"ugrave\", \"yacute\", \"ydieresis\", \"zcaron\", \"exclamsmall\", \"Hungarumlautsmall\", \"dollaroldstyle\", \"dollarsuperior\", \"ampersandsmall\", \"Acutesmall\", \"parenleftsuperior\", \"parenrightsuperior\", \"twodotenleader\", \"onedotenleader\", \"zerooldstyle\", \"oneoldstyle\", \"twooldstyle\", \"threeoldstyle\", \"fouroldstyle\", \"fiveoldstyle\", \"sixoldstyle\", \"sevenoldstyle\", \"eightoldstyle\", \"nineoldstyle\", \"commasuperior\", \"threequartersemdash\", \"periodsuperior\", \"questionsmall\", \"asuperior\", \"bsuperior\", \"centsuperior\", \"dsuperior\", \"esuperior\", \"isuperior\", \"lsuperior\", \"msuperior\", \"nsuperior\", \"osuperior\", \"rsuperior\", \"ssuperior\", \"tsuperior\", \"ff\", \"ffi\", \"ffl\", \"parenleftinferior\", \"parenrightinferior\", \"Circumflexsmall\", \"hyphensuperior\", \"Gravesmall\", \"Asmall\", \"Bsmall\", \"Csmall\", \"Dsmall\", \"Esmall\", \"Fsmall\", \"Gsmall\", \"Hsmall\", \"Ismall\", \"Jsmall\", \"Ksmall\", \"Lsmall\", \"Msmall\", \"Nsmall\", \"Osmall\", \"Psmall\", \"Qsmall\", \"Rsmall\", \"Ssmall\", \"Tsmall\", \"Usmall\", \"Vsmall\", \"Wsmall\", \"Xsmall\", \"Ysmall\", \"Zsmall\", \"colonmonetary\", \"onefitted\", \"rupiah\", \"Tildesmall\", \"exclamdownsmall\", \"centoldstyle\", \"Lslashsmall\", \"Scaronsmall\", \"Zcaronsmall\", \"Dieresissmall\", \"Brevesmall\", \"Caronsmall\", \"Dotaccentsmall\", \"Macronsmall\", \"figuredash\", \"hypheninferior\", \"Ogoneksmall\", \"Ringsmall\", \"Cedillasmall\", \"questiondownsmall\", \"oneeighth\", \"threeeighths\", \"fiveeighths\", \"seveneighths\", \"onethird\", \"twothirds\", \"zerosuperior\", \"foursuperior\", \"fivesuperior\", \"sixsuperior\", \"sevensuperior\", \"eightsuperior\", \"ninesuperior\", \"zeroinferior\", \"oneinferior\", \"twoinferior\", \"threeinferior\", \"fourinferior\", \"fiveinferior\", \"sixinferior\", \"seveninferior\", \"eightinferior\", \"nineinferior\", \"centinferior\", \"dollarinferior\", \"periodinferior\", \"commainferior\", \"Agravesmall\", \"Aacutesmall\", \"Acircumflexsmall\", \"Atildesmall\", \"Adieresissmall\", \"Aringsmall\", \"AEsmall\", \"Ccedillasmall\", \"Egravesmall\", \"Eacutesmall\", \"Ecircumflexsmall\", \"Edieresissmall\", \"Igravesmall\", \"Iacutesmall\", \"Icircumflexsmall\", \"Idieresissmall\", \"Ethsmall\", \"Ntildesmall\", \"Ogravesmall\", \"Oacutesmall\", \"Ocircumflexsmall\", \"Otildesmall\", \"Odieresissmall\", \"OEsmall\", \"Oslashsmall\", \"Ugravesmall\", \"Uacutesmall\", \"Ucircumflexsmall\", \"Udieresissmall\", \"Yacutesmall\", \"Thornsmall\", \"Ydieresissmall\", \"001.000\", \"001.001\", \"001.002\", \"001.003\", \"Black\", \"Bold\", \"Book\", \"Light\", \"Medium\", \"Regular\", \"Roman\", \"Semibold\"];\nconst NUM_STANDARD_CFF_STRINGS = 391;\nconst CharstringValidationData = [null, {\n  id: \"hstem\",\n  min: 2,\n  stackClearing: true,\n  stem: true\n}, null, {\n  id: \"vstem\",\n  min: 2,\n  stackClearing: true,\n  stem: true\n}, {\n  id: \"vmoveto\",\n  min: 1,\n  stackClearing: true\n}, {\n  id: \"rlineto\",\n  min: 2,\n  resetStack: true\n}, {\n  id: \"hlineto\",\n  min: 1,\n  resetStack: true\n}, {\n  id: \"vlineto\",\n  min: 1,\n  resetStack: true\n}, {\n  id: \"rrcurveto\",\n  min: 6,\n  resetStack: true\n}, null, {\n  id: \"callsubr\",\n  min: 1,\n  undefStack: true\n}, {\n  id: \"return\",\n  min: 0,\n  undefStack: true\n}, null, null, {\n  id: \"endchar\",\n  min: 0,\n  stackClearing: true\n}, null, null, null, {\n  id: \"hstemhm\",\n  min: 2,\n  stackClearing: true,\n  stem: true\n}, {\n  id: \"hintmask\",\n  min: 0,\n  stackClearing: true\n}, {\n  id: \"cntrmask\",\n  min: 0,\n  stackClearing: true\n}, {\n  id: \"rmoveto\",\n  min: 2,\n  stackClearing: true\n}, {\n  id: \"hmoveto\",\n  min: 1,\n  stackClearing: true\n}, {\n  id: \"vstemhm\",\n  min: 2,\n  stackClearing: true,\n  stem: true\n}, {\n  id: \"rcurveline\",\n  min: 8,\n  resetStack: true\n}, {\n  id: \"rlinecurve\",\n  min: 8,\n  resetStack: true\n}, {\n  id: \"vvcurveto\",\n  min: 4,\n  resetStack: true\n}, {\n  id: \"hhcurveto\",\n  min: 4,\n  resetStack: true\n}, null, {\n  id: \"callgsubr\",\n  min: 1,\n  undefStack: true\n}, {\n  id: \"vhcurveto\",\n  min: 4,\n  resetStack: true\n}, {\n  id: \"hvcurveto\",\n  min: 4,\n  resetStack: true\n}];\nconst CharstringValidationData12 = [null, null, null, {\n  id: \"and\",\n  min: 2,\n  stackDelta: -1\n}, {\n  id: \"or\",\n  min: 2,\n  stackDelta: -1\n}, {\n  id: \"not\",\n  min: 1,\n  stackDelta: 0\n}, null, null, null, {\n  id: \"abs\",\n  min: 1,\n  stackDelta: 0\n}, {\n  id: \"add\",\n  min: 2,\n  stackDelta: -1,\n  stackFn(stack, index) {\n    stack[index - 2] = stack[index - 2] + stack[index - 1];\n  }\n}, {\n  id: \"sub\",\n  min: 2,\n  stackDelta: -1,\n  stackFn(stack, index) {\n    stack[index - 2] = stack[index - 2] - stack[index - 1];\n  }\n}, {\n  id: \"div\",\n  min: 2,\n  stackDelta: -1,\n  stackFn(stack, index) {\n    stack[index - 2] = stack[index - 2] / stack[index - 1];\n  }\n}, null, {\n  id: \"neg\",\n  min: 1,\n  stackDelta: 0,\n  stackFn(stack, index) {\n    stack[index - 1] = -stack[index - 1];\n  }\n}, {\n  id: \"eq\",\n  min: 2,\n  stackDelta: -1\n}, null, null, {\n  id: \"drop\",\n  min: 1,\n  stackDelta: -1\n}, null, {\n  id: \"put\",\n  min: 2,\n  stackDelta: -2\n}, {\n  id: \"get\",\n  min: 1,\n  stackDelta: 0\n}, {\n  id: \"ifelse\",\n  min: 4,\n  stackDelta: -3\n}, {\n  id: \"random\",\n  min: 0,\n  stackDelta: 1\n}, {\n  id: \"mul\",\n  min: 2,\n  stackDelta: -1,\n  stackFn(stack, index) {\n    stack[index - 2] = stack[index - 2] * stack[index - 1];\n  }\n}, null, {\n  id: \"sqrt\",\n  min: 1,\n  stackDelta: 0\n}, {\n  id: \"dup\",\n  min: 1,\n  stackDelta: 1\n}, {\n  id: \"exch\",\n  min: 2,\n  stackDelta: 0\n}, {\n  id: \"index\",\n  min: 2,\n  stackDelta: 0\n}, {\n  id: \"roll\",\n  min: 3,\n  stackDelta: -2\n}, null, null, null, {\n  id: \"hflex\",\n  min: 7,\n  resetStack: true\n}, {\n  id: \"flex\",\n  min: 13,\n  resetStack: true\n}, {\n  id: \"hflex1\",\n  min: 9,\n  resetStack: true\n}, {\n  id: \"flex1\",\n  min: 11,\n  resetStack: true\n}];\nclass CFFParser {\n  constructor(file, properties, seacAnalysisEnabled) {\n    this.bytes = file.getBytes();\n    this.properties = properties;\n    this.seacAnalysisEnabled = !!seacAnalysisEnabled;\n  }\n  parse() {\n    const properties = this.properties;\n    const cff = new CFF();\n    this.cff = cff;\n    const header = this.parseHeader();\n    const nameIndex = this.parseIndex(header.endPos);\n    const topDictIndex = this.parseIndex(nameIndex.endPos);\n    const stringIndex = this.parseIndex(topDictIndex.endPos);\n    const globalSubrIndex = this.parseIndex(stringIndex.endPos);\n    const topDictParsed = this.parseDict(topDictIndex.obj.get(0));\n    const topDict = this.createDict(CFFTopDict, topDictParsed, cff.strings);\n    cff.header = header.obj;\n    cff.names = this.parseNameIndex(nameIndex.obj);\n    cff.strings = this.parseStringIndex(stringIndex.obj);\n    cff.topDict = topDict;\n    cff.globalSubrIndex = globalSubrIndex.obj;\n    this.parsePrivateDict(cff.topDict);\n    cff.isCIDFont = topDict.hasName(\"ROS\");\n    const charStringOffset = topDict.getByName(\"CharStrings\");\n    const charStringIndex = this.parseIndex(charStringOffset).obj;\n    const fontMatrix = topDict.getByName(\"FontMatrix\");\n    if (fontMatrix) {\n      properties.fontMatrix = fontMatrix;\n    }\n    const fontBBox = topDict.getByName(\"FontBBox\");\n    if (fontBBox) {\n      properties.ascent = Math.max(fontBBox[3], fontBBox[1]);\n      properties.descent = Math.min(fontBBox[1], fontBBox[3]);\n      properties.ascentScaled = true;\n    }\n    let charset, encoding;\n    if (cff.isCIDFont) {\n      const fdArrayIndex = this.parseIndex(topDict.getByName(\"FDArray\")).obj;\n      for (let i = 0, ii = fdArrayIndex.count; i < ii; ++i) {\n        const dictRaw = fdArrayIndex.get(i);\n        const fontDict = this.createDict(CFFTopDict, this.parseDict(dictRaw), cff.strings);\n        this.parsePrivateDict(fontDict);\n        cff.fdArray.push(fontDict);\n      }\n      encoding = null;\n      charset = this.parseCharsets(topDict.getByName(\"charset\"), charStringIndex.count, cff.strings, true);\n      cff.fdSelect = this.parseFDSelect(topDict.getByName(\"FDSelect\"), charStringIndex.count);\n    } else {\n      charset = this.parseCharsets(topDict.getByName(\"charset\"), charStringIndex.count, cff.strings, false);\n      encoding = this.parseEncoding(topDict.getByName(\"Encoding\"), properties, cff.strings, charset.charset);\n    }\n    cff.charset = charset;\n    cff.encoding = encoding;\n    const charStringsAndSeacs = this.parseCharStrings({\n      charStrings: charStringIndex,\n      localSubrIndex: topDict.privateDict.subrsIndex,\n      globalSubrIndex: globalSubrIndex.obj,\n      fdSelect: cff.fdSelect,\n      fdArray: cff.fdArray,\n      privateDict: topDict.privateDict\n    });\n    cff.charStrings = charStringsAndSeacs.charStrings;\n    cff.seacs = charStringsAndSeacs.seacs;\n    cff.widths = charStringsAndSeacs.widths;\n    return cff;\n  }\n  parseHeader() {\n    let bytes = this.bytes;\n    const bytesLength = bytes.length;\n    let offset = 0;\n    while (offset < bytesLength && bytes[offset] !== 1) {\n      ++offset;\n    }\n    if (offset >= bytesLength) {\n      throw new FormatError(\"Invalid CFF header\");\n    }\n    if (offset !== 0) {\n      info(\"cff data is shifted\");\n      bytes = bytes.subarray(offset);\n      this.bytes = bytes;\n    }\n    const major = bytes[0];\n    const minor = bytes[1];\n    const hdrSize = bytes[2];\n    const offSize = bytes[3];\n    const header = new CFFHeader(major, minor, hdrSize, offSize);\n    return {\n      obj: header,\n      endPos: hdrSize\n    };\n  }\n  parseDict(dict) {\n    let pos = 0;\n    function parseOperand() {\n      let value = dict[pos++];\n      if (value === 30) {\n        return parseFloatOperand();\n      } else if (value === 28) {\n        value = dict[pos++];\n        value = (value << 24 | dict[pos++] << 16) >> 16;\n        return value;\n      } else if (value === 29) {\n        value = dict[pos++];\n        value = value << 8 | dict[pos++];\n        value = value << 8 | dict[pos++];\n        value = value << 8 | dict[pos++];\n        return value;\n      } else if (value >= 32 && value <= 246) {\n        return value - 139;\n      } else if (value >= 247 && value <= 250) {\n        return (value - 247) * 256 + dict[pos++] + 108;\n      } else if (value >= 251 && value <= 254) {\n        return -((value - 251) * 256) - dict[pos++] - 108;\n      }\n      warn('CFFParser_parseDict: \"' + value + '\" is a reserved command.');\n      return NaN;\n    }\n    function parseFloatOperand() {\n      let str = \"\";\n      const eof = 15;\n      const lookup = [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \".\", \"E\", \"E-\", null, \"-\"];\n      const length = dict.length;\n      while (pos < length) {\n        const b = dict[pos++];\n        const b1 = b >> 4;\n        const b2 = b & 15;\n        if (b1 === eof) {\n          break;\n        }\n        str += lookup[b1];\n        if (b2 === eof) {\n          break;\n        }\n        str += lookup[b2];\n      }\n      return parseFloat(str);\n    }\n    let operands = [];\n    const entries = [];\n    pos = 0;\n    const end = dict.length;\n    while (pos < end) {\n      let b = dict[pos];\n      if (b <= 21) {\n        if (b === 12) {\n          b = b << 8 | dict[++pos];\n        }\n        entries.push([b, operands]);\n        operands = [];\n        ++pos;\n      } else {\n        operands.push(parseOperand());\n      }\n    }\n    return entries;\n  }\n  parseIndex(pos) {\n    const cffIndex = new CFFIndex();\n    const bytes = this.bytes;\n    const count = bytes[pos++] << 8 | bytes[pos++];\n    const offsets = [];\n    let end = pos;\n    let i, ii;\n    if (count !== 0) {\n      const offsetSize = bytes[pos++];\n      const startPos = pos + (count + 1) * offsetSize - 1;\n      for (i = 0, ii = count + 1; i < ii; ++i) {\n        let offset = 0;\n        for (let j = 0; j < offsetSize; ++j) {\n          offset <<= 8;\n          offset += bytes[pos++];\n        }\n        offsets.push(startPos + offset);\n      }\n      end = offsets[count];\n    }\n    for (i = 0, ii = offsets.length - 1; i < ii; ++i) {\n      const offsetStart = offsets[i];\n      const offsetEnd = offsets[i + 1];\n      cffIndex.add(bytes.subarray(offsetStart, offsetEnd));\n    }\n    return {\n      obj: cffIndex,\n      endPos: end\n    };\n  }\n  parseNameIndex(index) {\n    const names = [];\n    for (let i = 0, ii = index.count; i < ii; ++i) {\n      const name = index.get(i);\n      names.push(bytesToString(name));\n    }\n    return names;\n  }\n  parseStringIndex(index) {\n    const strings = new CFFStrings();\n    for (let i = 0, ii = index.count; i < ii; ++i) {\n      const data = index.get(i);\n      strings.add(bytesToString(data));\n    }\n    return strings;\n  }\n  createDict(Type, dict, strings) {\n    const cffDict = new Type(strings);\n    for (const [key, value] of dict) {\n      cffDict.setByKey(key, value);\n    }\n    return cffDict;\n  }\n  parseCharString(state, data, localSubrIndex, globalSubrIndex) {\n    if (!data || state.callDepth > MAX_SUBR_NESTING) {\n      return false;\n    }\n    let stackSize = state.stackSize;\n    const stack = state.stack;\n    let length = data.length;\n    for (let j = 0; j < length;) {\n      const value = data[j++];\n      let validationCommand = null;\n      if (value === 12) {\n        const q = data[j++];\n        if (q === 0) {\n          data[j - 2] = 139;\n          data[j - 1] = 22;\n          stackSize = 0;\n        } else {\n          validationCommand = CharstringValidationData12[q];\n        }\n      } else if (value === 28) {\n        stack[stackSize] = (data[j] << 24 | data[j + 1] << 16) >> 16;\n        j += 2;\n        stackSize++;\n      } else if (value === 14) {\n        if (stackSize >= 4) {\n          stackSize -= 4;\n          if (this.seacAnalysisEnabled) {\n            state.seac = stack.slice(stackSize, stackSize + 4);\n            return false;\n          }\n        }\n        validationCommand = CharstringValidationData[value];\n      } else if (value >= 32 && value <= 246) {\n        stack[stackSize] = value - 139;\n        stackSize++;\n      } else if (value >= 247 && value <= 254) {\n        stack[stackSize] = value < 251 ? (value - 247 << 8) + data[j] + 108 : -(value - 251 << 8) - data[j] - 108;\n        j++;\n        stackSize++;\n      } else if (value === 255) {\n        stack[stackSize] = (data[j] << 24 | data[j + 1] << 16 | data[j + 2] << 8 | data[j + 3]) / 65536;\n        j += 4;\n        stackSize++;\n      } else if (value === 19 || value === 20) {\n        state.hints += stackSize >> 1;\n        if (state.hints === 0) {\n          data.copyWithin(j - 1, j, -1);\n          j -= 1;\n          length -= 1;\n          continue;\n        }\n        j += state.hints + 7 >> 3;\n        stackSize %= 2;\n        validationCommand = CharstringValidationData[value];\n      } else if (value === 10 || value === 29) {\n        const subrsIndex = value === 10 ? localSubrIndex : globalSubrIndex;\n        if (!subrsIndex) {\n          validationCommand = CharstringValidationData[value];\n          warn(\"Missing subrsIndex for \" + validationCommand.id);\n          return false;\n        }\n        let bias = 32768;\n        if (subrsIndex.count < 1240) {\n          bias = 107;\n        } else if (subrsIndex.count < 33900) {\n          bias = 1131;\n        }\n        const subrNumber = stack[--stackSize] + bias;\n        if (subrNumber < 0 || subrNumber >= subrsIndex.count || isNaN(subrNumber)) {\n          validationCommand = CharstringValidationData[value];\n          warn(\"Out of bounds subrIndex for \" + validationCommand.id);\n          return false;\n        }\n        state.stackSize = stackSize;\n        state.callDepth++;\n        const valid = this.parseCharString(state, subrsIndex.get(subrNumber), localSubrIndex, globalSubrIndex);\n        if (!valid) {\n          return false;\n        }\n        state.callDepth--;\n        stackSize = state.stackSize;\n        continue;\n      } else if (value === 11) {\n        state.stackSize = stackSize;\n        return true;\n      } else if (value === 0 && j === data.length) {\n        data[j - 1] = 14;\n        validationCommand = CharstringValidationData[14];\n      } else if (value === 9) {\n        data.copyWithin(j - 1, j, -1);\n        j -= 1;\n        length -= 1;\n        continue;\n      } else {\n        validationCommand = CharstringValidationData[value];\n      }\n      if (validationCommand) {\n        if (validationCommand.stem) {\n          state.hints += stackSize >> 1;\n          if (value === 3 || value === 23) {\n            state.hasVStems = true;\n          } else if (state.hasVStems && (value === 1 || value === 18)) {\n            warn(\"CFF stem hints are in wrong order\");\n            data[j - 1] = value === 1 ? 3 : 23;\n          }\n        }\n        if (\"min\" in validationCommand) {\n          if (!state.undefStack && stackSize < validationCommand.min) {\n            warn(\"Not enough parameters for \" + validationCommand.id + \"; actual: \" + stackSize + \", expected: \" + validationCommand.min);\n            if (stackSize === 0) {\n              data[j - 1] = 14;\n              return true;\n            }\n            return false;\n          }\n        }\n        if (state.firstStackClearing && validationCommand.stackClearing) {\n          state.firstStackClearing = false;\n          stackSize -= validationCommand.min;\n          if (stackSize >= 2 && validationCommand.stem) {\n            stackSize %= 2;\n          } else if (stackSize > 1) {\n            warn(\"Found too many parameters for stack-clearing command\");\n          }\n          if (stackSize > 0) {\n            state.width = stack[stackSize - 1];\n          }\n        }\n        if (\"stackDelta\" in validationCommand) {\n          if (\"stackFn\" in validationCommand) {\n            validationCommand.stackFn(stack, stackSize);\n          }\n          stackSize += validationCommand.stackDelta;\n        } else if (validationCommand.stackClearing) {\n          stackSize = 0;\n        } else if (validationCommand.resetStack) {\n          stackSize = 0;\n          state.undefStack = false;\n        } else if (validationCommand.undefStack) {\n          stackSize = 0;\n          state.undefStack = true;\n          state.firstStackClearing = false;\n        }\n      }\n    }\n    if (length < data.length) {\n      data.fill(14, length);\n    }\n    state.stackSize = stackSize;\n    return true;\n  }\n  parseCharStrings({\n    charStrings,\n    localSubrIndex,\n    globalSubrIndex,\n    fdSelect,\n    fdArray,\n    privateDict\n  }) {\n    const seacs = [];\n    const widths = [];\n    const count = charStrings.count;\n    for (let i = 0; i < count; i++) {\n      const charstring = charStrings.get(i);\n      const state = {\n        callDepth: 0,\n        stackSize: 0,\n        stack: [],\n        undefStack: true,\n        hints: 0,\n        firstStackClearing: true,\n        seac: null,\n        width: null,\n        hasVStems: false\n      };\n      let valid = true;\n      let localSubrToUse = null;\n      let privateDictToUse = privateDict;\n      if (fdSelect && fdArray.length) {\n        const fdIndex = fdSelect.getFDIndex(i);\n        if (fdIndex === -1) {\n          warn(\"Glyph index is not in fd select.\");\n          valid = false;\n        }\n        if (fdIndex >= fdArray.length) {\n          warn(\"Invalid fd index for glyph index.\");\n          valid = false;\n        }\n        if (valid) {\n          privateDictToUse = fdArray[fdIndex].privateDict;\n          localSubrToUse = privateDictToUse.subrsIndex;\n        }\n      } else if (localSubrIndex) {\n        localSubrToUse = localSubrIndex;\n      }\n      if (valid) {\n        valid = this.parseCharString(state, charstring, localSubrToUse, globalSubrIndex);\n      }\n      if (state.width !== null) {\n        const nominalWidth = privateDictToUse.getByName(\"nominalWidthX\");\n        widths[i] = nominalWidth + state.width;\n      } else {\n        const defaultWidth = privateDictToUse.getByName(\"defaultWidthX\");\n        widths[i] = defaultWidth;\n      }\n      if (state.seac !== null) {\n        seacs[i] = state.seac;\n      }\n      if (!valid) {\n        charStrings.set(i, new Uint8Array([14]));\n      }\n    }\n    return {\n      charStrings,\n      seacs,\n      widths\n    };\n  }\n  emptyPrivateDictionary(parentDict) {\n    const privateDict = this.createDict(CFFPrivateDict, [], parentDict.strings);\n    parentDict.setByKey(18, [0, 0]);\n    parentDict.privateDict = privateDict;\n  }\n  parsePrivateDict(parentDict) {\n    if (!parentDict.hasName(\"Private\")) {\n      this.emptyPrivateDictionary(parentDict);\n      return;\n    }\n    const privateOffset = parentDict.getByName(\"Private\");\n    if (!Array.isArray(privateOffset) || privateOffset.length !== 2) {\n      parentDict.removeByName(\"Private\");\n      return;\n    }\n    const size = privateOffset[0];\n    const offset = privateOffset[1];\n    if (size === 0 || offset >= this.bytes.length) {\n      this.emptyPrivateDictionary(parentDict);\n      return;\n    }\n    const privateDictEnd = offset + size;\n    const dictData = this.bytes.subarray(offset, privateDictEnd);\n    const dict = this.parseDict(dictData);\n    const privateDict = this.createDict(CFFPrivateDict, dict, parentDict.strings);\n    parentDict.privateDict = privateDict;\n    if (privateDict.getByName(\"ExpansionFactor\") === 0) {\n      privateDict.setByName(\"ExpansionFactor\", 0.06);\n    }\n    if (!privateDict.getByName(\"Subrs\")) {\n      return;\n    }\n    const subrsOffset = privateDict.getByName(\"Subrs\");\n    const relativeOffset = offset + subrsOffset;\n    if (subrsOffset === 0 || relativeOffset >= this.bytes.length) {\n      this.emptyPrivateDictionary(parentDict);\n      return;\n    }\n    const subrsIndex = this.parseIndex(relativeOffset);\n    privateDict.subrsIndex = subrsIndex.obj;\n  }\n  parseCharsets(pos, length, strings, cid) {\n    if (pos === 0) {\n      return new CFFCharset(true, CFFCharsetPredefinedTypes.ISO_ADOBE, ISOAdobeCharset);\n    } else if (pos === 1) {\n      return new CFFCharset(true, CFFCharsetPredefinedTypes.EXPERT, ExpertCharset);\n    } else if (pos === 2) {\n      return new CFFCharset(true, CFFCharsetPredefinedTypes.EXPERT_SUBSET, ExpertSubsetCharset);\n    }\n    const bytes = this.bytes;\n    const start = pos;\n    const format = bytes[pos++];\n    const charset = [cid ? 0 : \".notdef\"];\n    let id, count, i;\n    length -= 1;\n    switch (format) {\n      case 0:\n        for (i = 0; i < length; i++) {\n          id = bytes[pos++] << 8 | bytes[pos++];\n          charset.push(cid ? id : strings.get(id));\n        }\n        break;\n      case 1:\n        while (charset.length <= length) {\n          id = bytes[pos++] << 8 | bytes[pos++];\n          count = bytes[pos++];\n          for (i = 0; i <= count; i++) {\n            charset.push(cid ? id++ : strings.get(id++));\n          }\n        }\n        break;\n      case 2:\n        while (charset.length <= length) {\n          id = bytes[pos++] << 8 | bytes[pos++];\n          count = bytes[pos++] << 8 | bytes[pos++];\n          for (i = 0; i <= count; i++) {\n            charset.push(cid ? id++ : strings.get(id++));\n          }\n        }\n        break;\n      default:\n        throw new FormatError(\"Unknown charset format\");\n    }\n    const end = pos;\n    const raw = bytes.subarray(start, end);\n    return new CFFCharset(false, format, charset, raw);\n  }\n  parseEncoding(pos, properties, strings, charset) {\n    const encoding = Object.create(null);\n    const bytes = this.bytes;\n    let predefined = false;\n    let format, i, ii;\n    let raw = null;\n    function readSupplement() {\n      const supplementsCount = bytes[pos++];\n      for (i = 0; i < supplementsCount; i++) {\n        const code = bytes[pos++];\n        const sid = (bytes[pos++] << 8) + (bytes[pos++] & 0xff);\n        encoding[code] = charset.indexOf(strings.get(sid));\n      }\n    }\n    if (pos === 0 || pos === 1) {\n      predefined = true;\n      format = pos;\n      const baseEncoding = pos ? ExpertEncoding : StandardEncoding;\n      for (i = 0, ii = charset.length; i < ii; i++) {\n        const index = baseEncoding.indexOf(charset[i]);\n        if (index !== -1) {\n          encoding[index] = i;\n        }\n      }\n    } else {\n      const dataStart = pos;\n      format = bytes[pos++];\n      switch (format & 0x7f) {\n        case 0:\n          const glyphsCount = bytes[pos++];\n          for (i = 1; i <= glyphsCount; i++) {\n            encoding[bytes[pos++]] = i;\n          }\n          break;\n        case 1:\n          const rangesCount = bytes[pos++];\n          let gid = 1;\n          for (i = 0; i < rangesCount; i++) {\n            const start = bytes[pos++];\n            const left = bytes[pos++];\n            for (let j = start; j <= start + left; j++) {\n              encoding[j] = gid++;\n            }\n          }\n          break;\n        default:\n          throw new FormatError(`Unknown encoding format: ${format} in CFF`);\n      }\n      const dataEnd = pos;\n      if (format & 0x80) {\n        bytes[dataStart] &= 0x7f;\n        readSupplement();\n      }\n      raw = bytes.subarray(dataStart, dataEnd);\n    }\n    format &= 0x7f;\n    return new CFFEncoding(predefined, format, encoding, raw);\n  }\n  parseFDSelect(pos, length) {\n    const bytes = this.bytes;\n    const format = bytes[pos++];\n    const fdSelect = [];\n    let i;\n    switch (format) {\n      case 0:\n        for (i = 0; i < length; ++i) {\n          const id = bytes[pos++];\n          fdSelect.push(id);\n        }\n        break;\n      case 3:\n        const rangesCount = bytes[pos++] << 8 | bytes[pos++];\n        for (i = 0; i < rangesCount; ++i) {\n          let first = bytes[pos++] << 8 | bytes[pos++];\n          if (i === 0 && first !== 0) {\n            warn(\"parseFDSelect: The first range must have a first GID of 0\" + \" -- trying to recover.\");\n            first = 0;\n          }\n          const fdIndex = bytes[pos++];\n          const next = bytes[pos] << 8 | bytes[pos + 1];\n          for (let j = first; j < next; ++j) {\n            fdSelect.push(fdIndex);\n          }\n        }\n        pos += 2;\n        break;\n      default:\n        throw new FormatError(`parseFDSelect: Unknown format \"${format}\".`);\n    }\n    if (fdSelect.length !== length) {\n      throw new FormatError(\"parseFDSelect: Invalid font data.\");\n    }\n    return new CFFFDSelect(format, fdSelect);\n  }\n}\nclass CFF {\n  constructor() {\n    this.header = null;\n    this.names = [];\n    this.topDict = null;\n    this.strings = new CFFStrings();\n    this.globalSubrIndex = null;\n    this.encoding = null;\n    this.charset = null;\n    this.charStrings = null;\n    this.fdArray = [];\n    this.fdSelect = null;\n    this.isCIDFont = false;\n  }\n  duplicateFirstGlyph() {\n    if (this.charStrings.count >= 65535) {\n      warn(\"Not enough space in charstrings to duplicate first glyph.\");\n      return;\n    }\n    const glyphZero = this.charStrings.get(0);\n    this.charStrings.add(glyphZero);\n    if (this.isCIDFont) {\n      this.fdSelect.fdSelect.push(this.fdSelect.fdSelect[0]);\n    }\n  }\n  hasGlyphId(id) {\n    if (id < 0 || id >= this.charStrings.count) {\n      return false;\n    }\n    const glyph = this.charStrings.get(id);\n    return glyph.length > 0;\n  }\n}\nclass CFFHeader {\n  constructor(major, minor, hdrSize, offSize) {\n    this.major = major;\n    this.minor = minor;\n    this.hdrSize = hdrSize;\n    this.offSize = offSize;\n  }\n}\nclass CFFStrings {\n  constructor() {\n    this.strings = [];\n  }\n  get(index) {\n    if (index >= 0 && index <= NUM_STANDARD_CFF_STRINGS - 1) {\n      return CFFStandardStrings[index];\n    }\n    if (index - NUM_STANDARD_CFF_STRINGS <= this.strings.length) {\n      return this.strings[index - NUM_STANDARD_CFF_STRINGS];\n    }\n    return CFFStandardStrings[0];\n  }\n  getSID(str) {\n    let index = CFFStandardStrings.indexOf(str);\n    if (index !== -1) {\n      return index;\n    }\n    index = this.strings.indexOf(str);\n    if (index !== -1) {\n      return index + NUM_STANDARD_CFF_STRINGS;\n    }\n    return -1;\n  }\n  add(value) {\n    this.strings.push(value);\n  }\n  get count() {\n    return this.strings.length;\n  }\n}\nclass CFFIndex {\n  constructor() {\n    this.objects = [];\n    this.length = 0;\n  }\n  add(data) {\n    this.length += data.length;\n    this.objects.push(data);\n  }\n  set(index, data) {\n    this.length += data.length - this.objects[index].length;\n    this.objects[index] = data;\n  }\n  get(index) {\n    return this.objects[index];\n  }\n  get count() {\n    return this.objects.length;\n  }\n}\nclass CFFDict {\n  constructor(tables, strings) {\n    this.keyToNameMap = tables.keyToNameMap;\n    this.nameToKeyMap = tables.nameToKeyMap;\n    this.defaults = tables.defaults;\n    this.types = tables.types;\n    this.opcodes = tables.opcodes;\n    this.order = tables.order;\n    this.strings = strings;\n    this.values = Object.create(null);\n  }\n  setByKey(key, value) {\n    if (!(key in this.keyToNameMap)) {\n      return false;\n    }\n    if (value.length === 0) {\n      return true;\n    }\n    for (const val of value) {\n      if (isNaN(val)) {\n        warn(`Invalid CFFDict value: \"${value}\" for key \"${key}\".`);\n        return true;\n      }\n    }\n    const type = this.types[key];\n    if (type === \"num\" || type === \"sid\" || type === \"offset\") {\n      value = value[0];\n    }\n    this.values[key] = value;\n    return true;\n  }\n  setByName(name, value) {\n    if (!(name in this.nameToKeyMap)) {\n      throw new FormatError(`Invalid dictionary name \"${name}\"`);\n    }\n    this.values[this.nameToKeyMap[name]] = value;\n  }\n  hasName(name) {\n    return this.nameToKeyMap[name] in this.values;\n  }\n  getByName(name) {\n    if (!(name in this.nameToKeyMap)) {\n      throw new FormatError(`Invalid dictionary name ${name}\"`);\n    }\n    const key = this.nameToKeyMap[name];\n    if (!(key in this.values)) {\n      return this.defaults[key];\n    }\n    return this.values[key];\n  }\n  removeByName(name) {\n    delete this.values[this.nameToKeyMap[name]];\n  }\n  static createTables(layout) {\n    const tables = {\n      keyToNameMap: {},\n      nameToKeyMap: {},\n      defaults: {},\n      types: {},\n      opcodes: {},\n      order: []\n    };\n    for (const entry of layout) {\n      const key = Array.isArray(entry[0]) ? (entry[0][0] << 8) + entry[0][1] : entry[0];\n      tables.keyToNameMap[key] = entry[1];\n      tables.nameToKeyMap[entry[1]] = key;\n      tables.types[key] = entry[2];\n      tables.defaults[key] = entry[3];\n      tables.opcodes[key] = Array.isArray(entry[0]) ? entry[0] : [entry[0]];\n      tables.order.push(key);\n    }\n    return tables;\n  }\n}\nconst CFFTopDictLayout = [[[12, 30], \"ROS\", [\"sid\", \"sid\", \"num\"], null], [[12, 20], \"SyntheticBase\", \"num\", null], [0, \"version\", \"sid\", null], [1, \"Notice\", \"sid\", null], [[12, 0], \"Copyright\", \"sid\", null], [2, \"FullName\", \"sid\", null], [3, \"FamilyName\", \"sid\", null], [4, \"Weight\", \"sid\", null], [[12, 1], \"isFixedPitch\", \"num\", 0], [[12, 2], \"ItalicAngle\", \"num\", 0], [[12, 3], \"UnderlinePosition\", \"num\", -100], [[12, 4], \"UnderlineThickness\", \"num\", 50], [[12, 5], \"PaintType\", \"num\", 0], [[12, 6], \"CharstringType\", \"num\", 2], [[12, 7], \"FontMatrix\", [\"num\", \"num\", \"num\", \"num\", \"num\", \"num\"], [0.001, 0, 0, 0.001, 0, 0]], [13, \"UniqueID\", \"num\", null], [5, \"FontBBox\", [\"num\", \"num\", \"num\", \"num\"], [0, 0, 0, 0]], [[12, 8], \"StrokeWidth\", \"num\", 0], [14, \"XUID\", \"array\", null], [15, \"charset\", \"offset\", 0], [16, \"Encoding\", \"offset\", 0], [17, \"CharStrings\", \"offset\", 0], [18, \"Private\", [\"offset\", \"offset\"], null], [[12, 21], \"PostScript\", \"sid\", null], [[12, 22], \"BaseFontName\", \"sid\", null], [[12, 23], \"BaseFontBlend\", \"delta\", null], [[12, 31], \"CIDFontVersion\", \"num\", 0], [[12, 32], \"CIDFontRevision\", \"num\", 0], [[12, 33], \"CIDFontType\", \"num\", 0], [[12, 34], \"CIDCount\", \"num\", 8720], [[12, 35], \"UIDBase\", \"num\", null], [[12, 37], \"FDSelect\", \"offset\", null], [[12, 36], \"FDArray\", \"offset\", null], [[12, 38], \"FontName\", \"sid\", null]];\nclass CFFTopDict extends CFFDict {\n  static get tables() {\n    return shadow(this, \"tables\", this.createTables(CFFTopDictLayout));\n  }\n  constructor(strings) {\n    super(CFFTopDict.tables, strings);\n    this.privateDict = null;\n  }\n}\nconst CFFPrivateDictLayout = [[6, \"BlueValues\", \"delta\", null], [7, \"OtherBlues\", \"delta\", null], [8, \"FamilyBlues\", \"delta\", null], [9, \"FamilyOtherBlues\", \"delta\", null], [[12, 9], \"BlueScale\", \"num\", 0.039625], [[12, 10], \"BlueShift\", \"num\", 7], [[12, 11], \"BlueFuzz\", \"num\", 1], [10, \"StdHW\", \"num\", null], [11, \"StdVW\", \"num\", null], [[12, 12], \"StemSnapH\", \"delta\", null], [[12, 13], \"StemSnapV\", \"delta\", null], [[12, 14], \"ForceBold\", \"num\", 0], [[12, 17], \"LanguageGroup\", \"num\", 0], [[12, 18], \"ExpansionFactor\", \"num\", 0.06], [[12, 19], \"initialRandomSeed\", \"num\", 0], [20, \"defaultWidthX\", \"num\", 0], [21, \"nominalWidthX\", \"num\", 0], [19, \"Subrs\", \"offset\", null]];\nclass CFFPrivateDict extends CFFDict {\n  static get tables() {\n    return shadow(this, \"tables\", this.createTables(CFFPrivateDictLayout));\n  }\n  constructor(strings) {\n    super(CFFPrivateDict.tables, strings);\n    this.subrsIndex = null;\n  }\n}\nconst CFFCharsetPredefinedTypes = {\n  ISO_ADOBE: 0,\n  EXPERT: 1,\n  EXPERT_SUBSET: 2\n};\nclass CFFCharset {\n  constructor(predefined, format, charset, raw) {\n    this.predefined = predefined;\n    this.format = format;\n    this.charset = charset;\n    this.raw = raw;\n  }\n}\nclass CFFEncoding {\n  constructor(predefined, format, encoding, raw) {\n    this.predefined = predefined;\n    this.format = format;\n    this.encoding = encoding;\n    this.raw = raw;\n  }\n}\nclass CFFFDSelect {\n  constructor(format, fdSelect) {\n    this.format = format;\n    this.fdSelect = fdSelect;\n  }\n  getFDIndex(glyphIndex) {\n    if (glyphIndex < 0 || glyphIndex >= this.fdSelect.length) {\n      return -1;\n    }\n    return this.fdSelect[glyphIndex];\n  }\n}\nclass CFFOffsetTracker {\n  constructor() {\n    this.offsets = Object.create(null);\n  }\n  isTracking(key) {\n    return key in this.offsets;\n  }\n  track(key, location) {\n    if (key in this.offsets) {\n      throw new FormatError(`Already tracking location of ${key}`);\n    }\n    this.offsets[key] = location;\n  }\n  offset(value) {\n    for (const key in this.offsets) {\n      this.offsets[key] += value;\n    }\n  }\n  setEntryLocation(key, values, output) {\n    if (!(key in this.offsets)) {\n      throw new FormatError(`Not tracking location of ${key}`);\n    }\n    const data = output.data;\n    const dataOffset = this.offsets[key];\n    const size = 5;\n    for (let i = 0, ii = values.length; i < ii; ++i) {\n      const offset0 = i * size + dataOffset;\n      const offset1 = offset0 + 1;\n      const offset2 = offset0 + 2;\n      const offset3 = offset0 + 3;\n      const offset4 = offset0 + 4;\n      if (data[offset0] !== 0x1d || data[offset1] !== 0 || data[offset2] !== 0 || data[offset3] !== 0 || data[offset4] !== 0) {\n        throw new FormatError(\"writing to an offset that is not empty\");\n      }\n      const value = values[i];\n      data[offset0] = 0x1d;\n      data[offset1] = value >> 24 & 0xff;\n      data[offset2] = value >> 16 & 0xff;\n      data[offset3] = value >> 8 & 0xff;\n      data[offset4] = value & 0xff;\n    }\n  }\n}\nclass CFFCompiler {\n  constructor(cff) {\n    this.cff = cff;\n  }\n  compile() {\n    const cff = this.cff;\n    const output = {\n      data: [],\n      length: 0,\n      add(data) {\n        try {\n          this.data.push(...data);\n        } catch {\n          this.data = this.data.concat(data);\n        }\n        this.length = this.data.length;\n      }\n    };\n    const header = this.compileHeader(cff.header);\n    output.add(header);\n    const nameIndex = this.compileNameIndex(cff.names);\n    output.add(nameIndex);\n    if (cff.isCIDFont) {\n      if (cff.topDict.hasName(\"FontMatrix\")) {\n        const base = cff.topDict.getByName(\"FontMatrix\");\n        cff.topDict.removeByName(\"FontMatrix\");\n        for (const subDict of cff.fdArray) {\n          let matrix = base.slice(0);\n          if (subDict.hasName(\"FontMatrix\")) {\n            matrix = Util.transform(matrix, subDict.getByName(\"FontMatrix\"));\n          }\n          subDict.setByName(\"FontMatrix\", matrix);\n        }\n      }\n    }\n    const xuid = cff.topDict.getByName(\"XUID\");\n    if (xuid?.length > 16) {\n      cff.topDict.removeByName(\"XUID\");\n    }\n    cff.topDict.setByName(\"charset\", 0);\n    let compiled = this.compileTopDicts([cff.topDict], output.length, cff.isCIDFont);\n    output.add(compiled.output);\n    const topDictTracker = compiled.trackers[0];\n    const stringIndex = this.compileStringIndex(cff.strings.strings);\n    output.add(stringIndex);\n    const globalSubrIndex = this.compileIndex(cff.globalSubrIndex);\n    output.add(globalSubrIndex);\n    if (cff.encoding && cff.topDict.hasName(\"Encoding\")) {\n      if (cff.encoding.predefined) {\n        topDictTracker.setEntryLocation(\"Encoding\", [cff.encoding.format], output);\n      } else {\n        const encoding = this.compileEncoding(cff.encoding);\n        topDictTracker.setEntryLocation(\"Encoding\", [output.length], output);\n        output.add(encoding);\n      }\n    }\n    const charset = this.compileCharset(cff.charset, cff.charStrings.count, cff.strings, cff.isCIDFont);\n    topDictTracker.setEntryLocation(\"charset\", [output.length], output);\n    output.add(charset);\n    const charStrings = this.compileCharStrings(cff.charStrings);\n    topDictTracker.setEntryLocation(\"CharStrings\", [output.length], output);\n    output.add(charStrings);\n    if (cff.isCIDFont) {\n      topDictTracker.setEntryLocation(\"FDSelect\", [output.length], output);\n      const fdSelect = this.compileFDSelect(cff.fdSelect);\n      output.add(fdSelect);\n      compiled = this.compileTopDicts(cff.fdArray, output.length, true);\n      topDictTracker.setEntryLocation(\"FDArray\", [output.length], output);\n      output.add(compiled.output);\n      const fontDictTrackers = compiled.trackers;\n      this.compilePrivateDicts(cff.fdArray, fontDictTrackers, output);\n    }\n    this.compilePrivateDicts([cff.topDict], [topDictTracker], output);\n    output.add([0]);\n    return output.data;\n  }\n  encodeNumber(value) {\n    if (Number.isInteger(value)) {\n      return this.encodeInteger(value);\n    }\n    return this.encodeFloat(value);\n  }\n  static get EncodeFloatRegExp() {\n    return shadow(this, \"EncodeFloatRegExp\", /\\.(\\d*?)(?:9{5,20}|0{5,20})\\d{0,2}(?:e(.+)|$)/);\n  }\n  encodeFloat(num) {\n    let value = num.toString();\n    const m = CFFCompiler.EncodeFloatRegExp.exec(value);\n    if (m) {\n      const epsilon = parseFloat(\"1e\" + ((m[2] ? +m[2] : 0) + m[1].length));\n      value = (Math.round(num * epsilon) / epsilon).toString();\n    }\n    let nibbles = \"\";\n    let i, ii;\n    for (i = 0, ii = value.length; i < ii; ++i) {\n      const a = value[i];\n      if (a === \"e\") {\n        nibbles += value[++i] === \"-\" ? \"c\" : \"b\";\n      } else if (a === \".\") {\n        nibbles += \"a\";\n      } else if (a === \"-\") {\n        nibbles += \"e\";\n      } else {\n        nibbles += a;\n      }\n    }\n    nibbles += nibbles.length & 1 ? \"f\" : \"ff\";\n    const out = [30];\n    for (i = 0, ii = nibbles.length; i < ii; i += 2) {\n      out.push(parseInt(nibbles.substring(i, i + 2), 16));\n    }\n    return out;\n  }\n  encodeInteger(value) {\n    let code;\n    if (value >= -107 && value <= 107) {\n      code = [value + 139];\n    } else if (value >= 108 && value <= 1131) {\n      value -= 108;\n      code = [(value >> 8) + 247, value & 0xff];\n    } else if (value >= -1131 && value <= -108) {\n      value = -value - 108;\n      code = [(value >> 8) + 251, value & 0xff];\n    } else if (value >= -32768 && value <= 32767) {\n      code = [0x1c, value >> 8 & 0xff, value & 0xff];\n    } else {\n      code = [0x1d, value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff];\n    }\n    return code;\n  }\n  compileHeader(header) {\n    return [header.major, header.minor, 4, header.offSize];\n  }\n  compileNameIndex(names) {\n    const nameIndex = new CFFIndex();\n    for (const name of names) {\n      const length = Math.min(name.length, 127);\n      let sanitizedName = new Array(length);\n      for (let j = 0; j < length; j++) {\n        let char = name[j];\n        if (char < \"!\" || char > \"~\" || char === \"[\" || char === \"]\" || char === \"(\" || char === \")\" || char === \"{\" || char === \"}\" || char === \"<\" || char === \">\" || char === \"/\" || char === \"%\") {\n          char = \"_\";\n        }\n        sanitizedName[j] = char;\n      }\n      sanitizedName = sanitizedName.join(\"\");\n      if (sanitizedName === \"\") {\n        sanitizedName = \"Bad_Font_Name\";\n      }\n      nameIndex.add(stringToBytes(sanitizedName));\n    }\n    return this.compileIndex(nameIndex);\n  }\n  compileTopDicts(dicts, length, removeCidKeys) {\n    const fontDictTrackers = [];\n    let fdArrayIndex = new CFFIndex();\n    for (const fontDict of dicts) {\n      if (removeCidKeys) {\n        fontDict.removeByName(\"CIDFontVersion\");\n        fontDict.removeByName(\"CIDFontRevision\");\n        fontDict.removeByName(\"CIDFontType\");\n        fontDict.removeByName(\"CIDCount\");\n        fontDict.removeByName(\"UIDBase\");\n      }\n      const fontDictTracker = new CFFOffsetTracker();\n      const fontDictData = this.compileDict(fontDict, fontDictTracker);\n      fontDictTrackers.push(fontDictTracker);\n      fdArrayIndex.add(fontDictData);\n      fontDictTracker.offset(length);\n    }\n    fdArrayIndex = this.compileIndex(fdArrayIndex, fontDictTrackers);\n    return {\n      trackers: fontDictTrackers,\n      output: fdArrayIndex\n    };\n  }\n  compilePrivateDicts(dicts, trackers, output) {\n    for (let i = 0, ii = dicts.length; i < ii; ++i) {\n      const fontDict = dicts[i];\n      const privateDict = fontDict.privateDict;\n      if (!privateDict || !fontDict.hasName(\"Private\")) {\n        throw new FormatError(\"There must be a private dictionary.\");\n      }\n      const privateDictTracker = new CFFOffsetTracker();\n      const privateDictData = this.compileDict(privateDict, privateDictTracker);\n      let outputLength = output.length;\n      privateDictTracker.offset(outputLength);\n      if (!privateDictData.length) {\n        outputLength = 0;\n      }\n      trackers[i].setEntryLocation(\"Private\", [privateDictData.length, outputLength], output);\n      output.add(privateDictData);\n      if (privateDict.subrsIndex && privateDict.hasName(\"Subrs\")) {\n        const subrs = this.compileIndex(privateDict.subrsIndex);\n        privateDictTracker.setEntryLocation(\"Subrs\", [privateDictData.length], output);\n        output.add(subrs);\n      }\n    }\n  }\n  compileDict(dict, offsetTracker) {\n    const out = [];\n    for (const key of dict.order) {\n      if (!(key in dict.values)) {\n        continue;\n      }\n      let values = dict.values[key];\n      let types = dict.types[key];\n      if (!Array.isArray(types)) {\n        types = [types];\n      }\n      if (!Array.isArray(values)) {\n        values = [values];\n      }\n      if (values.length === 0) {\n        continue;\n      }\n      for (let j = 0, jj = types.length; j < jj; ++j) {\n        const type = types[j];\n        const value = values[j];\n        switch (type) {\n          case \"num\":\n          case \"sid\":\n            out.push(...this.encodeNumber(value));\n            break;\n          case \"offset\":\n            const name = dict.keyToNameMap[key];\n            if (!offsetTracker.isTracking(name)) {\n              offsetTracker.track(name, out.length);\n            }\n            out.push(0x1d, 0, 0, 0, 0);\n            break;\n          case \"array\":\n          case \"delta\":\n            out.push(...this.encodeNumber(value));\n            for (let k = 1, kk = values.length; k < kk; ++k) {\n              out.push(...this.encodeNumber(values[k]));\n            }\n            break;\n          default:\n            throw new FormatError(`Unknown data type of ${type}`);\n        }\n      }\n      out.push(...dict.opcodes[key]);\n    }\n    return out;\n  }\n  compileStringIndex(strings) {\n    const stringIndex = new CFFIndex();\n    for (const string of strings) {\n      stringIndex.add(stringToBytes(string));\n    }\n    return this.compileIndex(stringIndex);\n  }\n  compileCharStrings(charStrings) {\n    const charStringsIndex = new CFFIndex();\n    for (let i = 0; i < charStrings.count; i++) {\n      const glyph = charStrings.get(i);\n      if (glyph.length === 0) {\n        charStringsIndex.add(new Uint8Array([0x8b, 0x0e]));\n        continue;\n      }\n      charStringsIndex.add(glyph);\n    }\n    return this.compileIndex(charStringsIndex);\n  }\n  compileCharset(charset, numGlyphs, strings, isCIDFont) {\n    let out;\n    const numGlyphsLessNotDef = numGlyphs - 1;\n    if (isCIDFont) {\n      out = new Uint8Array([2, 0, 0, numGlyphsLessNotDef >> 8 & 0xff, numGlyphsLessNotDef & 0xff]);\n    } else {\n      const length = 1 + numGlyphsLessNotDef * 2;\n      out = new Uint8Array(length);\n      out[0] = 0;\n      let charsetIndex = 0;\n      const numCharsets = charset.charset.length;\n      let warned = false;\n      for (let i = 1; i < out.length; i += 2) {\n        let sid = 0;\n        if (charsetIndex < numCharsets) {\n          const name = charset.charset[charsetIndex++];\n          sid = strings.getSID(name);\n          if (sid === -1) {\n            sid = 0;\n            if (!warned) {\n              warned = true;\n              warn(`Couldn't find ${name} in CFF strings`);\n            }\n          }\n        }\n        out[i] = sid >> 8 & 0xff;\n        out[i + 1] = sid & 0xff;\n      }\n    }\n    return this.compileTypedArray(out);\n  }\n  compileEncoding(encoding) {\n    return this.compileTypedArray(encoding.raw);\n  }\n  compileFDSelect(fdSelect) {\n    const format = fdSelect.format;\n    let out, i;\n    switch (format) {\n      case 0:\n        out = new Uint8Array(1 + fdSelect.fdSelect.length);\n        out[0] = format;\n        for (i = 0; i < fdSelect.fdSelect.length; i++) {\n          out[i + 1] = fdSelect.fdSelect[i];\n        }\n        break;\n      case 3:\n        const start = 0;\n        let lastFD = fdSelect.fdSelect[0];\n        const ranges = [format, 0, 0, start >> 8 & 0xff, start & 0xff, lastFD];\n        for (i = 1; i < fdSelect.fdSelect.length; i++) {\n          const currentFD = fdSelect.fdSelect[i];\n          if (currentFD !== lastFD) {\n            ranges.push(i >> 8 & 0xff, i & 0xff, currentFD);\n            lastFD = currentFD;\n          }\n        }\n        const numRanges = (ranges.length - 3) / 3;\n        ranges[1] = numRanges >> 8 & 0xff;\n        ranges[2] = numRanges & 0xff;\n        ranges.push(i >> 8 & 0xff, i & 0xff);\n        out = new Uint8Array(ranges);\n        break;\n    }\n    return this.compileTypedArray(out);\n  }\n  compileTypedArray(data) {\n    return Array.from(data);\n  }\n  compileIndex(index, trackers = []) {\n    const objects = index.objects;\n    const count = objects.length;\n    if (count === 0) {\n      return [0, 0];\n    }\n    const data = [count >> 8 & 0xff, count & 0xff];\n    let lastOffset = 1,\n      i;\n    for (i = 0; i < count; ++i) {\n      lastOffset += objects[i].length;\n    }\n    let offsetSize;\n    if (lastOffset < 0x100) {\n      offsetSize = 1;\n    } else if (lastOffset < 0x10000) {\n      offsetSize = 2;\n    } else if (lastOffset < 0x1000000) {\n      offsetSize = 3;\n    } else {\n      offsetSize = 4;\n    }\n    data.push(offsetSize);\n    let relativeOffset = 1;\n    for (i = 0; i < count + 1; i++) {\n      if (offsetSize === 1) {\n        data.push(relativeOffset & 0xff);\n      } else if (offsetSize === 2) {\n        data.push(relativeOffset >> 8 & 0xff, relativeOffset & 0xff);\n      } else if (offsetSize === 3) {\n        data.push(relativeOffset >> 16 & 0xff, relativeOffset >> 8 & 0xff, relativeOffset & 0xff);\n      } else {\n        data.push(relativeOffset >>> 24 & 0xff, relativeOffset >> 16 & 0xff, relativeOffset >> 8 & 0xff, relativeOffset & 0xff);\n      }\n      if (objects[i]) {\n        relativeOffset += objects[i].length;\n      }\n    }\n    for (i = 0; i < count; i++) {\n      if (trackers[i]) {\n        trackers[i].offset(data.length);\n      }\n      data.push(...objects[i]);\n    }\n    return data;\n  }\n}\n\n;// ./src/core/glyphlist.js\n\nconst getGlyphsUnicode = getLookupTableFactory(function (t) {\n  t.A = 0x0041;\n  t.AE = 0x00c6;\n  t.AEacute = 0x01fc;\n  t.AEmacron = 0x01e2;\n  t.AEsmall = 0xf7e6;\n  t.Aacute = 0x00c1;\n  t.Aacutesmall = 0xf7e1;\n  t.Abreve = 0x0102;\n  t.Abreveacute = 0x1eae;\n  t.Abrevecyrillic = 0x04d0;\n  t.Abrevedotbelow = 0x1eb6;\n  t.Abrevegrave = 0x1eb0;\n  t.Abrevehookabove = 0x1eb2;\n  t.Abrevetilde = 0x1eb4;\n  t.Acaron = 0x01cd;\n  t.Acircle = 0x24b6;\n  t.Acircumflex = 0x00c2;\n  t.Acircumflexacute = 0x1ea4;\n  t.Acircumflexdotbelow = 0x1eac;\n  t.Acircumflexgrave = 0x1ea6;\n  t.Acircumflexhookabove = 0x1ea8;\n  t.Acircumflexsmall = 0xf7e2;\n  t.Acircumflextilde = 0x1eaa;\n  t.Acute = 0xf6c9;\n  t.Acutesmall = 0xf7b4;\n  t.Acyrillic = 0x0410;\n  t.Adblgrave = 0x0200;\n  t.Adieresis = 0x00c4;\n  t.Adieresiscyrillic = 0x04d2;\n  t.Adieresismacron = 0x01de;\n  t.Adieresissmall = 0xf7e4;\n  t.Adotbelow = 0x1ea0;\n  t.Adotmacron = 0x01e0;\n  t.Agrave = 0x00c0;\n  t.Agravesmall = 0xf7e0;\n  t.Ahookabove = 0x1ea2;\n  t.Aiecyrillic = 0x04d4;\n  t.Ainvertedbreve = 0x0202;\n  t.Alpha = 0x0391;\n  t.Alphatonos = 0x0386;\n  t.Amacron = 0x0100;\n  t.Amonospace = 0xff21;\n  t.Aogonek = 0x0104;\n  t.Aring = 0x00c5;\n  t.Aringacute = 0x01fa;\n  t.Aringbelow = 0x1e00;\n  t.Aringsmall = 0xf7e5;\n  t.Asmall = 0xf761;\n  t.Atilde = 0x00c3;\n  t.Atildesmall = 0xf7e3;\n  t.Aybarmenian = 0x0531;\n  t.B = 0x0042;\n  t.Bcircle = 0x24b7;\n  t.Bdotaccent = 0x1e02;\n  t.Bdotbelow = 0x1e04;\n  t.Becyrillic = 0x0411;\n  t.Benarmenian = 0x0532;\n  t.Beta = 0x0392;\n  t.Bhook = 0x0181;\n  t.Blinebelow = 0x1e06;\n  t.Bmonospace = 0xff22;\n  t.Brevesmall = 0xf6f4;\n  t.Bsmall = 0xf762;\n  t.Btopbar = 0x0182;\n  t.C = 0x0043;\n  t.Caarmenian = 0x053e;\n  t.Cacute = 0x0106;\n  t.Caron = 0xf6ca;\n  t.Caronsmall = 0xf6f5;\n  t.Ccaron = 0x010c;\n  t.Ccedilla = 0x00c7;\n  t.Ccedillaacute = 0x1e08;\n  t.Ccedillasmall = 0xf7e7;\n  t.Ccircle = 0x24b8;\n  t.Ccircumflex = 0x0108;\n  t.Cdot = 0x010a;\n  t.Cdotaccent = 0x010a;\n  t.Cedillasmall = 0xf7b8;\n  t.Chaarmenian = 0x0549;\n  t.Cheabkhasiancyrillic = 0x04bc;\n  t.Checyrillic = 0x0427;\n  t.Chedescenderabkhasiancyrillic = 0x04be;\n  t.Chedescendercyrillic = 0x04b6;\n  t.Chedieresiscyrillic = 0x04f4;\n  t.Cheharmenian = 0x0543;\n  t.Chekhakassiancyrillic = 0x04cb;\n  t.Cheverticalstrokecyrillic = 0x04b8;\n  t.Chi = 0x03a7;\n  t.Chook = 0x0187;\n  t.Circumflexsmall = 0xf6f6;\n  t.Cmonospace = 0xff23;\n  t.Coarmenian = 0x0551;\n  t.Csmall = 0xf763;\n  t.D = 0x0044;\n  t.DZ = 0x01f1;\n  t.DZcaron = 0x01c4;\n  t.Daarmenian = 0x0534;\n  t.Dafrican = 0x0189;\n  t.Dcaron = 0x010e;\n  t.Dcedilla = 0x1e10;\n  t.Dcircle = 0x24b9;\n  t.Dcircumflexbelow = 0x1e12;\n  t.Dcroat = 0x0110;\n  t.Ddotaccent = 0x1e0a;\n  t.Ddotbelow = 0x1e0c;\n  t.Decyrillic = 0x0414;\n  t.Deicoptic = 0x03ee;\n  t.Delta = 0x2206;\n  t.Deltagreek = 0x0394;\n  t.Dhook = 0x018a;\n  t.Dieresis = 0xf6cb;\n  t.DieresisAcute = 0xf6cc;\n  t.DieresisGrave = 0xf6cd;\n  t.Dieresissmall = 0xf7a8;\n  t.Digammagreek = 0x03dc;\n  t.Djecyrillic = 0x0402;\n  t.Dlinebelow = 0x1e0e;\n  t.Dmonospace = 0xff24;\n  t.Dotaccentsmall = 0xf6f7;\n  t.Dslash = 0x0110;\n  t.Dsmall = 0xf764;\n  t.Dtopbar = 0x018b;\n  t.Dz = 0x01f2;\n  t.Dzcaron = 0x01c5;\n  t.Dzeabkhasiancyrillic = 0x04e0;\n  t.Dzecyrillic = 0x0405;\n  t.Dzhecyrillic = 0x040f;\n  t.E = 0x0045;\n  t.Eacute = 0x00c9;\n  t.Eacutesmall = 0xf7e9;\n  t.Ebreve = 0x0114;\n  t.Ecaron = 0x011a;\n  t.Ecedillabreve = 0x1e1c;\n  t.Echarmenian = 0x0535;\n  t.Ecircle = 0x24ba;\n  t.Ecircumflex = 0x00ca;\n  t.Ecircumflexacute = 0x1ebe;\n  t.Ecircumflexbelow = 0x1e18;\n  t.Ecircumflexdotbelow = 0x1ec6;\n  t.Ecircumflexgrave = 0x1ec0;\n  t.Ecircumflexhookabove = 0x1ec2;\n  t.Ecircumflexsmall = 0xf7ea;\n  t.Ecircumflextilde = 0x1ec4;\n  t.Ecyrillic = 0x0404;\n  t.Edblgrave = 0x0204;\n  t.Edieresis = 0x00cb;\n  t.Edieresissmall = 0xf7eb;\n  t.Edot = 0x0116;\n  t.Edotaccent = 0x0116;\n  t.Edotbelow = 0x1eb8;\n  t.Efcyrillic = 0x0424;\n  t.Egrave = 0x00c8;\n  t.Egravesmall = 0xf7e8;\n  t.Eharmenian = 0x0537;\n  t.Ehookabove = 0x1eba;\n  t.Eightroman = 0x2167;\n  t.Einvertedbreve = 0x0206;\n  t.Eiotifiedcyrillic = 0x0464;\n  t.Elcyrillic = 0x041b;\n  t.Elevenroman = 0x216a;\n  t.Emacron = 0x0112;\n  t.Emacronacute = 0x1e16;\n  t.Emacrongrave = 0x1e14;\n  t.Emcyrillic = 0x041c;\n  t.Emonospace = 0xff25;\n  t.Encyrillic = 0x041d;\n  t.Endescendercyrillic = 0x04a2;\n  t.Eng = 0x014a;\n  t.Enghecyrillic = 0x04a4;\n  t.Enhookcyrillic = 0x04c7;\n  t.Eogonek = 0x0118;\n  t.Eopen = 0x0190;\n  t.Epsilon = 0x0395;\n  t.Epsilontonos = 0x0388;\n  t.Ercyrillic = 0x0420;\n  t.Ereversed = 0x018e;\n  t.Ereversedcyrillic = 0x042d;\n  t.Escyrillic = 0x0421;\n  t.Esdescendercyrillic = 0x04aa;\n  t.Esh = 0x01a9;\n  t.Esmall = 0xf765;\n  t.Eta = 0x0397;\n  t.Etarmenian = 0x0538;\n  t.Etatonos = 0x0389;\n  t.Eth = 0x00d0;\n  t.Ethsmall = 0xf7f0;\n  t.Etilde = 0x1ebc;\n  t.Etildebelow = 0x1e1a;\n  t.Euro = 0x20ac;\n  t.Ezh = 0x01b7;\n  t.Ezhcaron = 0x01ee;\n  t.Ezhreversed = 0x01b8;\n  t.F = 0x0046;\n  t.Fcircle = 0x24bb;\n  t.Fdotaccent = 0x1e1e;\n  t.Feharmenian = 0x0556;\n  t.Feicoptic = 0x03e4;\n  t.Fhook = 0x0191;\n  t.Fitacyrillic = 0x0472;\n  t.Fiveroman = 0x2164;\n  t.Fmonospace = 0xff26;\n  t.Fourroman = 0x2163;\n  t.Fsmall = 0xf766;\n  t.G = 0x0047;\n  t.GBsquare = 0x3387;\n  t.Gacute = 0x01f4;\n  t.Gamma = 0x0393;\n  t.Gammaafrican = 0x0194;\n  t.Gangiacoptic = 0x03ea;\n  t.Gbreve = 0x011e;\n  t.Gcaron = 0x01e6;\n  t.Gcedilla = 0x0122;\n  t.Gcircle = 0x24bc;\n  t.Gcircumflex = 0x011c;\n  t.Gcommaaccent = 0x0122;\n  t.Gdot = 0x0120;\n  t.Gdotaccent = 0x0120;\n  t.Gecyrillic = 0x0413;\n  t.Ghadarmenian = 0x0542;\n  t.Ghemiddlehookcyrillic = 0x0494;\n  t.Ghestrokecyrillic = 0x0492;\n  t.Gheupturncyrillic = 0x0490;\n  t.Ghook = 0x0193;\n  t.Gimarmenian = 0x0533;\n  t.Gjecyrillic = 0x0403;\n  t.Gmacron = 0x1e20;\n  t.Gmonospace = 0xff27;\n  t.Grave = 0xf6ce;\n  t.Gravesmall = 0xf760;\n  t.Gsmall = 0xf767;\n  t.Gsmallhook = 0x029b;\n  t.Gstroke = 0x01e4;\n  t.H = 0x0048;\n  t.H18533 = 0x25cf;\n  t.H18543 = 0x25aa;\n  t.H18551 = 0x25ab;\n  t.H22073 = 0x25a1;\n  t.HPsquare = 0x33cb;\n  t.Haabkhasiancyrillic = 0x04a8;\n  t.Hadescendercyrillic = 0x04b2;\n  t.Hardsigncyrillic = 0x042a;\n  t.Hbar = 0x0126;\n  t.Hbrevebelow = 0x1e2a;\n  t.Hcedilla = 0x1e28;\n  t.Hcircle = 0x24bd;\n  t.Hcircumflex = 0x0124;\n  t.Hdieresis = 0x1e26;\n  t.Hdotaccent = 0x1e22;\n  t.Hdotbelow = 0x1e24;\n  t.Hmonospace = 0xff28;\n  t.Hoarmenian = 0x0540;\n  t.Horicoptic = 0x03e8;\n  t.Hsmall = 0xf768;\n  t.Hungarumlaut = 0xf6cf;\n  t.Hungarumlautsmall = 0xf6f8;\n  t.Hzsquare = 0x3390;\n  t.I = 0x0049;\n  t.IAcyrillic = 0x042f;\n  t.IJ = 0x0132;\n  t.IUcyrillic = 0x042e;\n  t.Iacute = 0x00cd;\n  t.Iacutesmall = 0xf7ed;\n  t.Ibreve = 0x012c;\n  t.Icaron = 0x01cf;\n  t.Icircle = 0x24be;\n  t.Icircumflex = 0x00ce;\n  t.Icircumflexsmall = 0xf7ee;\n  t.Icyrillic = 0x0406;\n  t.Idblgrave = 0x0208;\n  t.Idieresis = 0x00cf;\n  t.Idieresisacute = 0x1e2e;\n  t.Idieresiscyrillic = 0x04e4;\n  t.Idieresissmall = 0xf7ef;\n  t.Idot = 0x0130;\n  t.Idotaccent = 0x0130;\n  t.Idotbelow = 0x1eca;\n  t.Iebrevecyrillic = 0x04d6;\n  t.Iecyrillic = 0x0415;\n  t.Ifraktur = 0x2111;\n  t.Igrave = 0x00cc;\n  t.Igravesmall = 0xf7ec;\n  t.Ihookabove = 0x1ec8;\n  t.Iicyrillic = 0x0418;\n  t.Iinvertedbreve = 0x020a;\n  t.Iishortcyrillic = 0x0419;\n  t.Imacron = 0x012a;\n  t.Imacroncyrillic = 0x04e2;\n  t.Imonospace = 0xff29;\n  t.Iniarmenian = 0x053b;\n  t.Iocyrillic = 0x0401;\n  t.Iogonek = 0x012e;\n  t.Iota = 0x0399;\n  t.Iotaafrican = 0x0196;\n  t.Iotadieresis = 0x03aa;\n  t.Iotatonos = 0x038a;\n  t.Ismall = 0xf769;\n  t.Istroke = 0x0197;\n  t.Itilde = 0x0128;\n  t.Itildebelow = 0x1e2c;\n  t.Izhitsacyrillic = 0x0474;\n  t.Izhitsadblgravecyrillic = 0x0476;\n  t.J = 0x004a;\n  t.Jaarmenian = 0x0541;\n  t.Jcircle = 0x24bf;\n  t.Jcircumflex = 0x0134;\n  t.Jecyrillic = 0x0408;\n  t.Jheharmenian = 0x054b;\n  t.Jmonospace = 0xff2a;\n  t.Jsmall = 0xf76a;\n  t.K = 0x004b;\n  t.KBsquare = 0x3385;\n  t.KKsquare = 0x33cd;\n  t.Kabashkircyrillic = 0x04a0;\n  t.Kacute = 0x1e30;\n  t.Kacyrillic = 0x041a;\n  t.Kadescendercyrillic = 0x049a;\n  t.Kahookcyrillic = 0x04c3;\n  t.Kappa = 0x039a;\n  t.Kastrokecyrillic = 0x049e;\n  t.Kaverticalstrokecyrillic = 0x049c;\n  t.Kcaron = 0x01e8;\n  t.Kcedilla = 0x0136;\n  t.Kcircle = 0x24c0;\n  t.Kcommaaccent = 0x0136;\n  t.Kdotbelow = 0x1e32;\n  t.Keharmenian = 0x0554;\n  t.Kenarmenian = 0x053f;\n  t.Khacyrillic = 0x0425;\n  t.Kheicoptic = 0x03e6;\n  t.Khook = 0x0198;\n  t.Kjecyrillic = 0x040c;\n  t.Klinebelow = 0x1e34;\n  t.Kmonospace = 0xff2b;\n  t.Koppacyrillic = 0x0480;\n  t.Koppagreek = 0x03de;\n  t.Ksicyrillic = 0x046e;\n  t.Ksmall = 0xf76b;\n  t.L = 0x004c;\n  t.LJ = 0x01c7;\n  t.LL = 0xf6bf;\n  t.Lacute = 0x0139;\n  t.Lambda = 0x039b;\n  t.Lcaron = 0x013d;\n  t.Lcedilla = 0x013b;\n  t.Lcircle = 0x24c1;\n  t.Lcircumflexbelow = 0x1e3c;\n  t.Lcommaaccent = 0x013b;\n  t.Ldot = 0x013f;\n  t.Ldotaccent = 0x013f;\n  t.Ldotbelow = 0x1e36;\n  t.Ldotbelowmacron = 0x1e38;\n  t.Liwnarmenian = 0x053c;\n  t.Lj = 0x01c8;\n  t.Ljecyrillic = 0x0409;\n  t.Llinebelow = 0x1e3a;\n  t.Lmonospace = 0xff2c;\n  t.Lslash = 0x0141;\n  t.Lslashsmall = 0xf6f9;\n  t.Lsmall = 0xf76c;\n  t.M = 0x004d;\n  t.MBsquare = 0x3386;\n  t.Macron = 0xf6d0;\n  t.Macronsmall = 0xf7af;\n  t.Macute = 0x1e3e;\n  t.Mcircle = 0x24c2;\n  t.Mdotaccent = 0x1e40;\n  t.Mdotbelow = 0x1e42;\n  t.Menarmenian = 0x0544;\n  t.Mmonospace = 0xff2d;\n  t.Msmall = 0xf76d;\n  t.Mturned = 0x019c;\n  t.Mu = 0x039c;\n  t.N = 0x004e;\n  t.NJ = 0x01ca;\n  t.Nacute = 0x0143;\n  t.Ncaron = 0x0147;\n  t.Ncedilla = 0x0145;\n  t.Ncircle = 0x24c3;\n  t.Ncircumflexbelow = 0x1e4a;\n  t.Ncommaaccent = 0x0145;\n  t.Ndotaccent = 0x1e44;\n  t.Ndotbelow = 0x1e46;\n  t.Nhookleft = 0x019d;\n  t.Nineroman = 0x2168;\n  t.Nj = 0x01cb;\n  t.Njecyrillic = 0x040a;\n  t.Nlinebelow = 0x1e48;\n  t.Nmonospace = 0xff2e;\n  t.Nowarmenian = 0x0546;\n  t.Nsmall = 0xf76e;\n  t.Ntilde = 0x00d1;\n  t.Ntildesmall = 0xf7f1;\n  t.Nu = 0x039d;\n  t.O = 0x004f;\n  t.OE = 0x0152;\n  t.OEsmall = 0xf6fa;\n  t.Oacute = 0x00d3;\n  t.Oacutesmall = 0xf7f3;\n  t.Obarredcyrillic = 0x04e8;\n  t.Obarreddieresiscyrillic = 0x04ea;\n  t.Obreve = 0x014e;\n  t.Ocaron = 0x01d1;\n  t.Ocenteredtilde = 0x019f;\n  t.Ocircle = 0x24c4;\n  t.Ocircumflex = 0x00d4;\n  t.Ocircumflexacute = 0x1ed0;\n  t.Ocircumflexdotbelow = 0x1ed8;\n  t.Ocircumflexgrave = 0x1ed2;\n  t.Ocircumflexhookabove = 0x1ed4;\n  t.Ocircumflexsmall = 0xf7f4;\n  t.Ocircumflextilde = 0x1ed6;\n  t.Ocyrillic = 0x041e;\n  t.Odblacute = 0x0150;\n  t.Odblgrave = 0x020c;\n  t.Odieresis = 0x00d6;\n  t.Odieresiscyrillic = 0x04e6;\n  t.Odieresissmall = 0xf7f6;\n  t.Odotbelow = 0x1ecc;\n  t.Ogoneksmall = 0xf6fb;\n  t.Ograve = 0x00d2;\n  t.Ogravesmall = 0xf7f2;\n  t.Oharmenian = 0x0555;\n  t.Ohm = 0x2126;\n  t.Ohookabove = 0x1ece;\n  t.Ohorn = 0x01a0;\n  t.Ohornacute = 0x1eda;\n  t.Ohorndotbelow = 0x1ee2;\n  t.Ohorngrave = 0x1edc;\n  t.Ohornhookabove = 0x1ede;\n  t.Ohorntilde = 0x1ee0;\n  t.Ohungarumlaut = 0x0150;\n  t.Oi = 0x01a2;\n  t.Oinvertedbreve = 0x020e;\n  t.Omacron = 0x014c;\n  t.Omacronacute = 0x1e52;\n  t.Omacrongrave = 0x1e50;\n  t.Omega = 0x2126;\n  t.Omegacyrillic = 0x0460;\n  t.Omegagreek = 0x03a9;\n  t.Omegaroundcyrillic = 0x047a;\n  t.Omegatitlocyrillic = 0x047c;\n  t.Omegatonos = 0x038f;\n  t.Omicron = 0x039f;\n  t.Omicrontonos = 0x038c;\n  t.Omonospace = 0xff2f;\n  t.Oneroman = 0x2160;\n  t.Oogonek = 0x01ea;\n  t.Oogonekmacron = 0x01ec;\n  t.Oopen = 0x0186;\n  t.Oslash = 0x00d8;\n  t.Oslashacute = 0x01fe;\n  t.Oslashsmall = 0xf7f8;\n  t.Osmall = 0xf76f;\n  t.Ostrokeacute = 0x01fe;\n  t.Otcyrillic = 0x047e;\n  t.Otilde = 0x00d5;\n  t.Otildeacute = 0x1e4c;\n  t.Otildedieresis = 0x1e4e;\n  t.Otildesmall = 0xf7f5;\n  t.P = 0x0050;\n  t.Pacute = 0x1e54;\n  t.Pcircle = 0x24c5;\n  t.Pdotaccent = 0x1e56;\n  t.Pecyrillic = 0x041f;\n  t.Peharmenian = 0x054a;\n  t.Pemiddlehookcyrillic = 0x04a6;\n  t.Phi = 0x03a6;\n  t.Phook = 0x01a4;\n  t.Pi = 0x03a0;\n  t.Piwrarmenian = 0x0553;\n  t.Pmonospace = 0xff30;\n  t.Psi = 0x03a8;\n  t.Psicyrillic = 0x0470;\n  t.Psmall = 0xf770;\n  t.Q = 0x0051;\n  t.Qcircle = 0x24c6;\n  t.Qmonospace = 0xff31;\n  t.Qsmall = 0xf771;\n  t.R = 0x0052;\n  t.Raarmenian = 0x054c;\n  t.Racute = 0x0154;\n  t.Rcaron = 0x0158;\n  t.Rcedilla = 0x0156;\n  t.Rcircle = 0x24c7;\n  t.Rcommaaccent = 0x0156;\n  t.Rdblgrave = 0x0210;\n  t.Rdotaccent = 0x1e58;\n  t.Rdotbelow = 0x1e5a;\n  t.Rdotbelowmacron = 0x1e5c;\n  t.Reharmenian = 0x0550;\n  t.Rfraktur = 0x211c;\n  t.Rho = 0x03a1;\n  t.Ringsmall = 0xf6fc;\n  t.Rinvertedbreve = 0x0212;\n  t.Rlinebelow = 0x1e5e;\n  t.Rmonospace = 0xff32;\n  t.Rsmall = 0xf772;\n  t.Rsmallinverted = 0x0281;\n  t.Rsmallinvertedsuperior = 0x02b6;\n  t.S = 0x0053;\n  t.SF010000 = 0x250c;\n  t.SF020000 = 0x2514;\n  t.SF030000 = 0x2510;\n  t.SF040000 = 0x2518;\n  t.SF050000 = 0x253c;\n  t.SF060000 = 0x252c;\n  t.SF070000 = 0x2534;\n  t.SF080000 = 0x251c;\n  t.SF090000 = 0x2524;\n  t.SF100000 = 0x2500;\n  t.SF110000 = 0x2502;\n  t.SF190000 = 0x2561;\n  t.SF200000 = 0x2562;\n  t.SF210000 = 0x2556;\n  t.SF220000 = 0x2555;\n  t.SF230000 = 0x2563;\n  t.SF240000 = 0x2551;\n  t.SF250000 = 0x2557;\n  t.SF260000 = 0x255d;\n  t.SF270000 = 0x255c;\n  t.SF280000 = 0x255b;\n  t.SF360000 = 0x255e;\n  t.SF370000 = 0x255f;\n  t.SF380000 = 0x255a;\n  t.SF390000 = 0x2554;\n  t.SF400000 = 0x2569;\n  t.SF410000 = 0x2566;\n  t.SF420000 = 0x2560;\n  t.SF430000 = 0x2550;\n  t.SF440000 = 0x256c;\n  t.SF450000 = 0x2567;\n  t.SF460000 = 0x2568;\n  t.SF470000 = 0x2564;\n  t.SF480000 = 0x2565;\n  t.SF490000 = 0x2559;\n  t.SF500000 = 0x2558;\n  t.SF510000 = 0x2552;\n  t.SF520000 = 0x2553;\n  t.SF530000 = 0x256b;\n  t.SF540000 = 0x256a;\n  t.Sacute = 0x015a;\n  t.Sacutedotaccent = 0x1e64;\n  t.Sampigreek = 0x03e0;\n  t.Scaron = 0x0160;\n  t.Scarondotaccent = 0x1e66;\n  t.Scaronsmall = 0xf6fd;\n  t.Scedilla = 0x015e;\n  t.Schwa = 0x018f;\n  t.Schwacyrillic = 0x04d8;\n  t.Schwadieresiscyrillic = 0x04da;\n  t.Scircle = 0x24c8;\n  t.Scircumflex = 0x015c;\n  t.Scommaaccent = 0x0218;\n  t.Sdotaccent = 0x1e60;\n  t.Sdotbelow = 0x1e62;\n  t.Sdotbelowdotaccent = 0x1e68;\n  t.Seharmenian = 0x054d;\n  t.Sevenroman = 0x2166;\n  t.Shaarmenian = 0x0547;\n  t.Shacyrillic = 0x0428;\n  t.Shchacyrillic = 0x0429;\n  t.Sheicoptic = 0x03e2;\n  t.Shhacyrillic = 0x04ba;\n  t.Shimacoptic = 0x03ec;\n  t.Sigma = 0x03a3;\n  t.Sixroman = 0x2165;\n  t.Smonospace = 0xff33;\n  t.Softsigncyrillic = 0x042c;\n  t.Ssmall = 0xf773;\n  t.Stigmagreek = 0x03da;\n  t.T = 0x0054;\n  t.Tau = 0x03a4;\n  t.Tbar = 0x0166;\n  t.Tcaron = 0x0164;\n  t.Tcedilla = 0x0162;\n  t.Tcircle = 0x24c9;\n  t.Tcircumflexbelow = 0x1e70;\n  t.Tcommaaccent = 0x0162;\n  t.Tdotaccent = 0x1e6a;\n  t.Tdotbelow = 0x1e6c;\n  t.Tecyrillic = 0x0422;\n  t.Tedescendercyrillic = 0x04ac;\n  t.Tenroman = 0x2169;\n  t.Tetsecyrillic = 0x04b4;\n  t.Theta = 0x0398;\n  t.Thook = 0x01ac;\n  t.Thorn = 0x00de;\n  t.Thornsmall = 0xf7fe;\n  t.Threeroman = 0x2162;\n  t.Tildesmall = 0xf6fe;\n  t.Tiwnarmenian = 0x054f;\n  t.Tlinebelow = 0x1e6e;\n  t.Tmonospace = 0xff34;\n  t.Toarmenian = 0x0539;\n  t.Tonefive = 0x01bc;\n  t.Tonesix = 0x0184;\n  t.Tonetwo = 0x01a7;\n  t.Tretroflexhook = 0x01ae;\n  t.Tsecyrillic = 0x0426;\n  t.Tshecyrillic = 0x040b;\n  t.Tsmall = 0xf774;\n  t.Twelveroman = 0x216b;\n  t.Tworoman = 0x2161;\n  t.U = 0x0055;\n  t.Uacute = 0x00da;\n  t.Uacutesmall = 0xf7fa;\n  t.Ubreve = 0x016c;\n  t.Ucaron = 0x01d3;\n  t.Ucircle = 0x24ca;\n  t.Ucircumflex = 0x00db;\n  t.Ucircumflexbelow = 0x1e76;\n  t.Ucircumflexsmall = 0xf7fb;\n  t.Ucyrillic = 0x0423;\n  t.Udblacute = 0x0170;\n  t.Udblgrave = 0x0214;\n  t.Udieresis = 0x00dc;\n  t.Udieresisacute = 0x01d7;\n  t.Udieresisbelow = 0x1e72;\n  t.Udieresiscaron = 0x01d9;\n  t.Udieresiscyrillic = 0x04f0;\n  t.Udieresisgrave = 0x01db;\n  t.Udieresismacron = 0x01d5;\n  t.Udieresissmall = 0xf7fc;\n  t.Udotbelow = 0x1ee4;\n  t.Ugrave = 0x00d9;\n  t.Ugravesmall = 0xf7f9;\n  t.Uhookabove = 0x1ee6;\n  t.Uhorn = 0x01af;\n  t.Uhornacute = 0x1ee8;\n  t.Uhorndotbelow = 0x1ef0;\n  t.Uhorngrave = 0x1eea;\n  t.Uhornhookabove = 0x1eec;\n  t.Uhorntilde = 0x1eee;\n  t.Uhungarumlaut = 0x0170;\n  t.Uhungarumlautcyrillic = 0x04f2;\n  t.Uinvertedbreve = 0x0216;\n  t.Ukcyrillic = 0x0478;\n  t.Umacron = 0x016a;\n  t.Umacroncyrillic = 0x04ee;\n  t.Umacrondieresis = 0x1e7a;\n  t.Umonospace = 0xff35;\n  t.Uogonek = 0x0172;\n  t.Upsilon = 0x03a5;\n  t.Upsilon1 = 0x03d2;\n  t.Upsilonacutehooksymbolgreek = 0x03d3;\n  t.Upsilonafrican = 0x01b1;\n  t.Upsilondieresis = 0x03ab;\n  t.Upsilondieresishooksymbolgreek = 0x03d4;\n  t.Upsilonhooksymbol = 0x03d2;\n  t.Upsilontonos = 0x038e;\n  t.Uring = 0x016e;\n  t.Ushortcyrillic = 0x040e;\n  t.Usmall = 0xf775;\n  t.Ustraightcyrillic = 0x04ae;\n  t.Ustraightstrokecyrillic = 0x04b0;\n  t.Utilde = 0x0168;\n  t.Utildeacute = 0x1e78;\n  t.Utildebelow = 0x1e74;\n  t.V = 0x0056;\n  t.Vcircle = 0x24cb;\n  t.Vdotbelow = 0x1e7e;\n  t.Vecyrillic = 0x0412;\n  t.Vewarmenian = 0x054e;\n  t.Vhook = 0x01b2;\n  t.Vmonospace = 0xff36;\n  t.Voarmenian = 0x0548;\n  t.Vsmall = 0xf776;\n  t.Vtilde = 0x1e7c;\n  t.W = 0x0057;\n  t.Wacute = 0x1e82;\n  t.Wcircle = 0x24cc;\n  t.Wcircumflex = 0x0174;\n  t.Wdieresis = 0x1e84;\n  t.Wdotaccent = 0x1e86;\n  t.Wdotbelow = 0x1e88;\n  t.Wgrave = 0x1e80;\n  t.Wmonospace = 0xff37;\n  t.Wsmall = 0xf777;\n  t.X = 0x0058;\n  t.Xcircle = 0x24cd;\n  t.Xdieresis = 0x1e8c;\n  t.Xdotaccent = 0x1e8a;\n  t.Xeharmenian = 0x053d;\n  t.Xi = 0x039e;\n  t.Xmonospace = 0xff38;\n  t.Xsmall = 0xf778;\n  t.Y = 0x0059;\n  t.Yacute = 0x00dd;\n  t.Yacutesmall = 0xf7fd;\n  t.Yatcyrillic = 0x0462;\n  t.Ycircle = 0x24ce;\n  t.Ycircumflex = 0x0176;\n  t.Ydieresis = 0x0178;\n  t.Ydieresissmall = 0xf7ff;\n  t.Ydotaccent = 0x1e8e;\n  t.Ydotbelow = 0x1ef4;\n  t.Yericyrillic = 0x042b;\n  t.Yerudieresiscyrillic = 0x04f8;\n  t.Ygrave = 0x1ef2;\n  t.Yhook = 0x01b3;\n  t.Yhookabove = 0x1ef6;\n  t.Yiarmenian = 0x0545;\n  t.Yicyrillic = 0x0407;\n  t.Yiwnarmenian = 0x0552;\n  t.Ymonospace = 0xff39;\n  t.Ysmall = 0xf779;\n  t.Ytilde = 0x1ef8;\n  t.Yusbigcyrillic = 0x046a;\n  t.Yusbigiotifiedcyrillic = 0x046c;\n  t.Yuslittlecyrillic = 0x0466;\n  t.Yuslittleiotifiedcyrillic = 0x0468;\n  t.Z = 0x005a;\n  t.Zaarmenian = 0x0536;\n  t.Zacute = 0x0179;\n  t.Zcaron = 0x017d;\n  t.Zcaronsmall = 0xf6ff;\n  t.Zcircle = 0x24cf;\n  t.Zcircumflex = 0x1e90;\n  t.Zdot = 0x017b;\n  t.Zdotaccent = 0x017b;\n  t.Zdotbelow = 0x1e92;\n  t.Zecyrillic = 0x0417;\n  t.Zedescendercyrillic = 0x0498;\n  t.Zedieresiscyrillic = 0x04de;\n  t.Zeta = 0x0396;\n  t.Zhearmenian = 0x053a;\n  t.Zhebrevecyrillic = 0x04c1;\n  t.Zhecyrillic = 0x0416;\n  t.Zhedescendercyrillic = 0x0496;\n  t.Zhedieresiscyrillic = 0x04dc;\n  t.Zlinebelow = 0x1e94;\n  t.Zmonospace = 0xff3a;\n  t.Zsmall = 0xf77a;\n  t.Zstroke = 0x01b5;\n  t.a = 0x0061;\n  t.aabengali = 0x0986;\n  t.aacute = 0x00e1;\n  t.aadeva = 0x0906;\n  t.aagujarati = 0x0a86;\n  t.aagurmukhi = 0x0a06;\n  t.aamatragurmukhi = 0x0a3e;\n  t.aarusquare = 0x3303;\n  t.aavowelsignbengali = 0x09be;\n  t.aavowelsigndeva = 0x093e;\n  t.aavowelsigngujarati = 0x0abe;\n  t.abbreviationmarkarmenian = 0x055f;\n  t.abbreviationsigndeva = 0x0970;\n  t.abengali = 0x0985;\n  t.abopomofo = 0x311a;\n  t.abreve = 0x0103;\n  t.abreveacute = 0x1eaf;\n  t.abrevecyrillic = 0x04d1;\n  t.abrevedotbelow = 0x1eb7;\n  t.abrevegrave = 0x1eb1;\n  t.abrevehookabove = 0x1eb3;\n  t.abrevetilde = 0x1eb5;\n  t.acaron = 0x01ce;\n  t.acircle = 0x24d0;\n  t.acircumflex = 0x00e2;\n  t.acircumflexacute = 0x1ea5;\n  t.acircumflexdotbelow = 0x1ead;\n  t.acircumflexgrave = 0x1ea7;\n  t.acircumflexhookabove = 0x1ea9;\n  t.acircumflextilde = 0x1eab;\n  t.acute = 0x00b4;\n  t.acutebelowcmb = 0x0317;\n  t.acutecmb = 0x0301;\n  t.acutecomb = 0x0301;\n  t.acutedeva = 0x0954;\n  t.acutelowmod = 0x02cf;\n  t.acutetonecmb = 0x0341;\n  t.acyrillic = 0x0430;\n  t.adblgrave = 0x0201;\n  t.addakgurmukhi = 0x0a71;\n  t.adeva = 0x0905;\n  t.adieresis = 0x00e4;\n  t.adieresiscyrillic = 0x04d3;\n  t.adieresismacron = 0x01df;\n  t.adotbelow = 0x1ea1;\n  t.adotmacron = 0x01e1;\n  t.ae = 0x00e6;\n  t.aeacute = 0x01fd;\n  t.aekorean = 0x3150;\n  t.aemacron = 0x01e3;\n  t.afii00208 = 0x2015;\n  t.afii08941 = 0x20a4;\n  t.afii10017 = 0x0410;\n  t.afii10018 = 0x0411;\n  t.afii10019 = 0x0412;\n  t.afii10020 = 0x0413;\n  t.afii10021 = 0x0414;\n  t.afii10022 = 0x0415;\n  t.afii10023 = 0x0401;\n  t.afii10024 = 0x0416;\n  t.afii10025 = 0x0417;\n  t.afii10026 = 0x0418;\n  t.afii10027 = 0x0419;\n  t.afii10028 = 0x041a;\n  t.afii10029 = 0x041b;\n  t.afii10030 = 0x041c;\n  t.afii10031 = 0x041d;\n  t.afii10032 = 0x041e;\n  t.afii10033 = 0x041f;\n  t.afii10034 = 0x0420;\n  t.afii10035 = 0x0421;\n  t.afii10036 = 0x0422;\n  t.afii10037 = 0x0423;\n  t.afii10038 = 0x0424;\n  t.afii10039 = 0x0425;\n  t.afii10040 = 0x0426;\n  t.afii10041 = 0x0427;\n  t.afii10042 = 0x0428;\n  t.afii10043 = 0x0429;\n  t.afii10044 = 0x042a;\n  t.afii10045 = 0x042b;\n  t.afii10046 = 0x042c;\n  t.afii10047 = 0x042d;\n  t.afii10048 = 0x042e;\n  t.afii10049 = 0x042f;\n  t.afii10050 = 0x0490;\n  t.afii10051 = 0x0402;\n  t.afii10052 = 0x0403;\n  t.afii10053 = 0x0404;\n  t.afii10054 = 0x0405;\n  t.afii10055 = 0x0406;\n  t.afii10056 = 0x0407;\n  t.afii10057 = 0x0408;\n  t.afii10058 = 0x0409;\n  t.afii10059 = 0x040a;\n  t.afii10060 = 0x040b;\n  t.afii10061 = 0x040c;\n  t.afii10062 = 0x040e;\n  t.afii10063 = 0xf6c4;\n  t.afii10064 = 0xf6c5;\n  t.afii10065 = 0x0430;\n  t.afii10066 = 0x0431;\n  t.afii10067 = 0x0432;\n  t.afii10068 = 0x0433;\n  t.afii10069 = 0x0434;\n  t.afii10070 = 0x0435;\n  t.afii10071 = 0x0451;\n  t.afii10072 = 0x0436;\n  t.afii10073 = 0x0437;\n  t.afii10074 = 0x0438;\n  t.afii10075 = 0x0439;\n  t.afii10076 = 0x043a;\n  t.afii10077 = 0x043b;\n  t.afii10078 = 0x043c;\n  t.afii10079 = 0x043d;\n  t.afii10080 = 0x043e;\n  t.afii10081 = 0x043f;\n  t.afii10082 = 0x0440;\n  t.afii10083 = 0x0441;\n  t.afii10084 = 0x0442;\n  t.afii10085 = 0x0443;\n  t.afii10086 = 0x0444;\n  t.afii10087 = 0x0445;\n  t.afii10088 = 0x0446;\n  t.afii10089 = 0x0447;\n  t.afii10090 = 0x0448;\n  t.afii10091 = 0x0449;\n  t.afii10092 = 0x044a;\n  t.afii10093 = 0x044b;\n  t.afii10094 = 0x044c;\n  t.afii10095 = 0x044d;\n  t.afii10096 = 0x044e;\n  t.afii10097 = 0x044f;\n  t.afii10098 = 0x0491;\n  t.afii10099 = 0x0452;\n  t.afii10100 = 0x0453;\n  t.afii10101 = 0x0454;\n  t.afii10102 = 0x0455;\n  t.afii10103 = 0x0456;\n  t.afii10104 = 0x0457;\n  t.afii10105 = 0x0458;\n  t.afii10106 = 0x0459;\n  t.afii10107 = 0x045a;\n  t.afii10108 = 0x045b;\n  t.afii10109 = 0x045c;\n  t.afii10110 = 0x045e;\n  t.afii10145 = 0x040f;\n  t.afii10146 = 0x0462;\n  t.afii10147 = 0x0472;\n  t.afii10148 = 0x0474;\n  t.afii10192 = 0xf6c6;\n  t.afii10193 = 0x045f;\n  t.afii10194 = 0x0463;\n  t.afii10195 = 0x0473;\n  t.afii10196 = 0x0475;\n  t.afii10831 = 0xf6c7;\n  t.afii10832 = 0xf6c8;\n  t.afii10846 = 0x04d9;\n  t.afii299 = 0x200e;\n  t.afii300 = 0x200f;\n  t.afii301 = 0x200d;\n  t.afii57381 = 0x066a;\n  t.afii57388 = 0x060c;\n  t.afii57392 = 0x0660;\n  t.afii57393 = 0x0661;\n  t.afii57394 = 0x0662;\n  t.afii57395 = 0x0663;\n  t.afii57396 = 0x0664;\n  t.afii57397 = 0x0665;\n  t.afii57398 = 0x0666;\n  t.afii57399 = 0x0667;\n  t.afii57400 = 0x0668;\n  t.afii57401 = 0x0669;\n  t.afii57403 = 0x061b;\n  t.afii57407 = 0x061f;\n  t.afii57409 = 0x0621;\n  t.afii57410 = 0x0622;\n  t.afii57411 = 0x0623;\n  t.afii57412 = 0x0624;\n  t.afii57413 = 0x0625;\n  t.afii57414 = 0x0626;\n  t.afii57415 = 0x0627;\n  t.afii57416 = 0x0628;\n  t.afii57417 = 0x0629;\n  t.afii57418 = 0x062a;\n  t.afii57419 = 0x062b;\n  t.afii57420 = 0x062c;\n  t.afii57421 = 0x062d;\n  t.afii57422 = 0x062e;\n  t.afii57423 = 0x062f;\n  t.afii57424 = 0x0630;\n  t.afii57425 = 0x0631;\n  t.afii57426 = 0x0632;\n  t.afii57427 = 0x0633;\n  t.afii57428 = 0x0634;\n  t.afii57429 = 0x0635;\n  t.afii57430 = 0x0636;\n  t.afii57431 = 0x0637;\n  t.afii57432 = 0x0638;\n  t.afii57433 = 0x0639;\n  t.afii57434 = 0x063a;\n  t.afii57440 = 0x0640;\n  t.afii57441 = 0x0641;\n  t.afii57442 = 0x0642;\n  t.afii57443 = 0x0643;\n  t.afii57444 = 0x0644;\n  t.afii57445 = 0x0645;\n  t.afii57446 = 0x0646;\n  t.afii57448 = 0x0648;\n  t.afii57449 = 0x0649;\n  t.afii57450 = 0x064a;\n  t.afii57451 = 0x064b;\n  t.afii57452 = 0x064c;\n  t.afii57453 = 0x064d;\n  t.afii57454 = 0x064e;\n  t.afii57455 = 0x064f;\n  t.afii57456 = 0x0650;\n  t.afii57457 = 0x0651;\n  t.afii57458 = 0x0652;\n  t.afii57470 = 0x0647;\n  t.afii57505 = 0x06a4;\n  t.afii57506 = 0x067e;\n  t.afii57507 = 0x0686;\n  t.afii57508 = 0x0698;\n  t.afii57509 = 0x06af;\n  t.afii57511 = 0x0679;\n  t.afii57512 = 0x0688;\n  t.afii57513 = 0x0691;\n  t.afii57514 = 0x06ba;\n  t.afii57519 = 0x06d2;\n  t.afii57534 = 0x06d5;\n  t.afii57636 = 0x20aa;\n  t.afii57645 = 0x05be;\n  t.afii57658 = 0x05c3;\n  t.afii57664 = 0x05d0;\n  t.afii57665 = 0x05d1;\n  t.afii57666 = 0x05d2;\n  t.afii57667 = 0x05d3;\n  t.afii57668 = 0x05d4;\n  t.afii57669 = 0x05d5;\n  t.afii57670 = 0x05d6;\n  t.afii57671 = 0x05d7;\n  t.afii57672 = 0x05d8;\n  t.afii57673 = 0x05d9;\n  t.afii57674 = 0x05da;\n  t.afii57675 = 0x05db;\n  t.afii57676 = 0x05dc;\n  t.afii57677 = 0x05dd;\n  t.afii57678 = 0x05de;\n  t.afii57679 = 0x05df;\n  t.afii57680 = 0x05e0;\n  t.afii57681 = 0x05e1;\n  t.afii57682 = 0x05e2;\n  t.afii57683 = 0x05e3;\n  t.afii57684 = 0x05e4;\n  t.afii57685 = 0x05e5;\n  t.afii57686 = 0x05e6;\n  t.afii57687 = 0x05e7;\n  t.afii57688 = 0x05e8;\n  t.afii57689 = 0x05e9;\n  t.afii57690 = 0x05ea;\n  t.afii57694 = 0xfb2a;\n  t.afii57695 = 0xfb2b;\n  t.afii57700 = 0xfb4b;\n  t.afii57705 = 0xfb1f;\n  t.afii57716 = 0x05f0;\n  t.afii57717 = 0x05f1;\n  t.afii57718 = 0x05f2;\n  t.afii57723 = 0xfb35;\n  t.afii57793 = 0x05b4;\n  t.afii57794 = 0x05b5;\n  t.afii57795 = 0x05b6;\n  t.afii57796 = 0x05bb;\n  t.afii57797 = 0x05b8;\n  t.afii57798 = 0x05b7;\n  t.afii57799 = 0x05b0;\n  t.afii57800 = 0x05b2;\n  t.afii57801 = 0x05b1;\n  t.afii57802 = 0x05b3;\n  t.afii57803 = 0x05c2;\n  t.afii57804 = 0x05c1;\n  t.afii57806 = 0x05b9;\n  t.afii57807 = 0x05bc;\n  t.afii57839 = 0x05bd;\n  t.afii57841 = 0x05bf;\n  t.afii57842 = 0x05c0;\n  t.afii57929 = 0x02bc;\n  t.afii61248 = 0x2105;\n  t.afii61289 = 0x2113;\n  t.afii61352 = 0x2116;\n  t.afii61573 = 0x202c;\n  t.afii61574 = 0x202d;\n  t.afii61575 = 0x202e;\n  t.afii61664 = 0x200c;\n  t.afii63167 = 0x066d;\n  t.afii64937 = 0x02bd;\n  t.agrave = 0x00e0;\n  t.agujarati = 0x0a85;\n  t.agurmukhi = 0x0a05;\n  t.ahiragana = 0x3042;\n  t.ahookabove = 0x1ea3;\n  t.aibengali = 0x0990;\n  t.aibopomofo = 0x311e;\n  t.aideva = 0x0910;\n  t.aiecyrillic = 0x04d5;\n  t.aigujarati = 0x0a90;\n  t.aigurmukhi = 0x0a10;\n  t.aimatragurmukhi = 0x0a48;\n  t.ainarabic = 0x0639;\n  t.ainfinalarabic = 0xfeca;\n  t.aininitialarabic = 0xfecb;\n  t.ainmedialarabic = 0xfecc;\n  t.ainvertedbreve = 0x0203;\n  t.aivowelsignbengali = 0x09c8;\n  t.aivowelsigndeva = 0x0948;\n  t.aivowelsigngujarati = 0x0ac8;\n  t.akatakana = 0x30a2;\n  t.akatakanahalfwidth = 0xff71;\n  t.akorean = 0x314f;\n  t.alef = 0x05d0;\n  t.alefarabic = 0x0627;\n  t.alefdageshhebrew = 0xfb30;\n  t.aleffinalarabic = 0xfe8e;\n  t.alefhamzaabovearabic = 0x0623;\n  t.alefhamzaabovefinalarabic = 0xfe84;\n  t.alefhamzabelowarabic = 0x0625;\n  t.alefhamzabelowfinalarabic = 0xfe88;\n  t.alefhebrew = 0x05d0;\n  t.aleflamedhebrew = 0xfb4f;\n  t.alefmaddaabovearabic = 0x0622;\n  t.alefmaddaabovefinalarabic = 0xfe82;\n  t.alefmaksuraarabic = 0x0649;\n  t.alefmaksurafinalarabic = 0xfef0;\n  t.alefmaksurainitialarabic = 0xfef3;\n  t.alefmaksuramedialarabic = 0xfef4;\n  t.alefpatahhebrew = 0xfb2e;\n  t.alefqamatshebrew = 0xfb2f;\n  t.aleph = 0x2135;\n  t.allequal = 0x224c;\n  t.alpha = 0x03b1;\n  t.alphatonos = 0x03ac;\n  t.amacron = 0x0101;\n  t.amonospace = 0xff41;\n  t.ampersand = 0x0026;\n  t.ampersandmonospace = 0xff06;\n  t.ampersandsmall = 0xf726;\n  t.amsquare = 0x33c2;\n  t.anbopomofo = 0x3122;\n  t.angbopomofo = 0x3124;\n  t.angbracketleft = 0x3008;\n  t.angbracketright = 0x3009;\n  t.angkhankhuthai = 0x0e5a;\n  t.angle = 0x2220;\n  t.anglebracketleft = 0x3008;\n  t.anglebracketleftvertical = 0xfe3f;\n  t.anglebracketright = 0x3009;\n  t.anglebracketrightvertical = 0xfe40;\n  t.angleleft = 0x2329;\n  t.angleright = 0x232a;\n  t.angstrom = 0x212b;\n  t.anoteleia = 0x0387;\n  t.anudattadeva = 0x0952;\n  t.anusvarabengali = 0x0982;\n  t.anusvaradeva = 0x0902;\n  t.anusvaragujarati = 0x0a82;\n  t.aogonek = 0x0105;\n  t.apaatosquare = 0x3300;\n  t.aparen = 0x249c;\n  t.apostrophearmenian = 0x055a;\n  t.apostrophemod = 0x02bc;\n  t.apple = 0xf8ff;\n  t.approaches = 0x2250;\n  t.approxequal = 0x2248;\n  t.approxequalorimage = 0x2252;\n  t.approximatelyequal = 0x2245;\n  t.araeaekorean = 0x318e;\n  t.araeakorean = 0x318d;\n  t.arc = 0x2312;\n  t.arighthalfring = 0x1e9a;\n  t.aring = 0x00e5;\n  t.aringacute = 0x01fb;\n  t.aringbelow = 0x1e01;\n  t.arrowboth = 0x2194;\n  t.arrowdashdown = 0x21e3;\n  t.arrowdashleft = 0x21e0;\n  t.arrowdashright = 0x21e2;\n  t.arrowdashup = 0x21e1;\n  t.arrowdblboth = 0x21d4;\n  t.arrowdbldown = 0x21d3;\n  t.arrowdblleft = 0x21d0;\n  t.arrowdblright = 0x21d2;\n  t.arrowdblup = 0x21d1;\n  t.arrowdown = 0x2193;\n  t.arrowdownleft = 0x2199;\n  t.arrowdownright = 0x2198;\n  t.arrowdownwhite = 0x21e9;\n  t.arrowheaddownmod = 0x02c5;\n  t.arrowheadleftmod = 0x02c2;\n  t.arrowheadrightmod = 0x02c3;\n  t.arrowheadupmod = 0x02c4;\n  t.arrowhorizex = 0xf8e7;\n  t.arrowleft = 0x2190;\n  t.arrowleftdbl = 0x21d0;\n  t.arrowleftdblstroke = 0x21cd;\n  t.arrowleftoverright = 0x21c6;\n  t.arrowleftwhite = 0x21e6;\n  t.arrowright = 0x2192;\n  t.arrowrightdblstroke = 0x21cf;\n  t.arrowrightheavy = 0x279e;\n  t.arrowrightoverleft = 0x21c4;\n  t.arrowrightwhite = 0x21e8;\n  t.arrowtableft = 0x21e4;\n  t.arrowtabright = 0x21e5;\n  t.arrowup = 0x2191;\n  t.arrowupdn = 0x2195;\n  t.arrowupdnbse = 0x21a8;\n  t.arrowupdownbase = 0x21a8;\n  t.arrowupleft = 0x2196;\n  t.arrowupleftofdown = 0x21c5;\n  t.arrowupright = 0x2197;\n  t.arrowupwhite = 0x21e7;\n  t.arrowvertex = 0xf8e6;\n  t.asciicircum = 0x005e;\n  t.asciicircummonospace = 0xff3e;\n  t.asciitilde = 0x007e;\n  t.asciitildemonospace = 0xff5e;\n  t.ascript = 0x0251;\n  t.ascriptturned = 0x0252;\n  t.asmallhiragana = 0x3041;\n  t.asmallkatakana = 0x30a1;\n  t.asmallkatakanahalfwidth = 0xff67;\n  t.asterisk = 0x002a;\n  t.asteriskaltonearabic = 0x066d;\n  t.asteriskarabic = 0x066d;\n  t.asteriskmath = 0x2217;\n  t.asteriskmonospace = 0xff0a;\n  t.asterisksmall = 0xfe61;\n  t.asterism = 0x2042;\n  t.asuperior = 0xf6e9;\n  t.asymptoticallyequal = 0x2243;\n  t.at = 0x0040;\n  t.atilde = 0x00e3;\n  t.atmonospace = 0xff20;\n  t.atsmall = 0xfe6b;\n  t.aturned = 0x0250;\n  t.aubengali = 0x0994;\n  t.aubopomofo = 0x3120;\n  t.audeva = 0x0914;\n  t.augujarati = 0x0a94;\n  t.augurmukhi = 0x0a14;\n  t.aulengthmarkbengali = 0x09d7;\n  t.aumatragurmukhi = 0x0a4c;\n  t.auvowelsignbengali = 0x09cc;\n  t.auvowelsigndeva = 0x094c;\n  t.auvowelsigngujarati = 0x0acc;\n  t.avagrahadeva = 0x093d;\n  t.aybarmenian = 0x0561;\n  t.ayin = 0x05e2;\n  t.ayinaltonehebrew = 0xfb20;\n  t.ayinhebrew = 0x05e2;\n  t.b = 0x0062;\n  t.babengali = 0x09ac;\n  t.backslash = 0x005c;\n  t.backslashmonospace = 0xff3c;\n  t.badeva = 0x092c;\n  t.bagujarati = 0x0aac;\n  t.bagurmukhi = 0x0a2c;\n  t.bahiragana = 0x3070;\n  t.bahtthai = 0x0e3f;\n  t.bakatakana = 0x30d0;\n  t.bar = 0x007c;\n  t.barmonospace = 0xff5c;\n  t.bbopomofo = 0x3105;\n  t.bcircle = 0x24d1;\n  t.bdotaccent = 0x1e03;\n  t.bdotbelow = 0x1e05;\n  t.beamedsixteenthnotes = 0x266c;\n  t.because = 0x2235;\n  t.becyrillic = 0x0431;\n  t.beharabic = 0x0628;\n  t.behfinalarabic = 0xfe90;\n  t.behinitialarabic = 0xfe91;\n  t.behiragana = 0x3079;\n  t.behmedialarabic = 0xfe92;\n  t.behmeeminitialarabic = 0xfc9f;\n  t.behmeemisolatedarabic = 0xfc08;\n  t.behnoonfinalarabic = 0xfc6d;\n  t.bekatakana = 0x30d9;\n  t.benarmenian = 0x0562;\n  t.bet = 0x05d1;\n  t.beta = 0x03b2;\n  t.betasymbolgreek = 0x03d0;\n  t.betdagesh = 0xfb31;\n  t.betdageshhebrew = 0xfb31;\n  t.bethebrew = 0x05d1;\n  t.betrafehebrew = 0xfb4c;\n  t.bhabengali = 0x09ad;\n  t.bhadeva = 0x092d;\n  t.bhagujarati = 0x0aad;\n  t.bhagurmukhi = 0x0a2d;\n  t.bhook = 0x0253;\n  t.bihiragana = 0x3073;\n  t.bikatakana = 0x30d3;\n  t.bilabialclick = 0x0298;\n  t.bindigurmukhi = 0x0a02;\n  t.birusquare = 0x3331;\n  t.blackcircle = 0x25cf;\n  t.blackdiamond = 0x25c6;\n  t.blackdownpointingtriangle = 0x25bc;\n  t.blackleftpointingpointer = 0x25c4;\n  t.blackleftpointingtriangle = 0x25c0;\n  t.blacklenticularbracketleft = 0x3010;\n  t.blacklenticularbracketleftvertical = 0xfe3b;\n  t.blacklenticularbracketright = 0x3011;\n  t.blacklenticularbracketrightvertical = 0xfe3c;\n  t.blacklowerlefttriangle = 0x25e3;\n  t.blacklowerrighttriangle = 0x25e2;\n  t.blackrectangle = 0x25ac;\n  t.blackrightpointingpointer = 0x25ba;\n  t.blackrightpointingtriangle = 0x25b6;\n  t.blacksmallsquare = 0x25aa;\n  t.blacksmilingface = 0x263b;\n  t.blacksquare = 0x25a0;\n  t.blackstar = 0x2605;\n  t.blackupperlefttriangle = 0x25e4;\n  t.blackupperrighttriangle = 0x25e5;\n  t.blackuppointingsmalltriangle = 0x25b4;\n  t.blackuppointingtriangle = 0x25b2;\n  t.blank = 0x2423;\n  t.blinebelow = 0x1e07;\n  t.block = 0x2588;\n  t.bmonospace = 0xff42;\n  t.bobaimaithai = 0x0e1a;\n  t.bohiragana = 0x307c;\n  t.bokatakana = 0x30dc;\n  t.bparen = 0x249d;\n  t.bqsquare = 0x33c3;\n  t.braceex = 0xf8f4;\n  t.braceleft = 0x007b;\n  t.braceleftbt = 0xf8f3;\n  t.braceleftmid = 0xf8f2;\n  t.braceleftmonospace = 0xff5b;\n  t.braceleftsmall = 0xfe5b;\n  t.bracelefttp = 0xf8f1;\n  t.braceleftvertical = 0xfe37;\n  t.braceright = 0x007d;\n  t.bracerightbt = 0xf8fe;\n  t.bracerightmid = 0xf8fd;\n  t.bracerightmonospace = 0xff5d;\n  t.bracerightsmall = 0xfe5c;\n  t.bracerighttp = 0xf8fc;\n  t.bracerightvertical = 0xfe38;\n  t.bracketleft = 0x005b;\n  t.bracketleftbt = 0xf8f0;\n  t.bracketleftex = 0xf8ef;\n  t.bracketleftmonospace = 0xff3b;\n  t.bracketlefttp = 0xf8ee;\n  t.bracketright = 0x005d;\n  t.bracketrightbt = 0xf8fb;\n  t.bracketrightex = 0xf8fa;\n  t.bracketrightmonospace = 0xff3d;\n  t.bracketrighttp = 0xf8f9;\n  t.breve = 0x02d8;\n  t.brevebelowcmb = 0x032e;\n  t.brevecmb = 0x0306;\n  t.breveinvertedbelowcmb = 0x032f;\n  t.breveinvertedcmb = 0x0311;\n  t.breveinverteddoublecmb = 0x0361;\n  t.bridgebelowcmb = 0x032a;\n  t.bridgeinvertedbelowcmb = 0x033a;\n  t.brokenbar = 0x00a6;\n  t.bstroke = 0x0180;\n  t.bsuperior = 0xf6ea;\n  t.btopbar = 0x0183;\n  t.buhiragana = 0x3076;\n  t.bukatakana = 0x30d6;\n  t.bullet = 0x2022;\n  t.bulletinverse = 0x25d8;\n  t.bulletoperator = 0x2219;\n  t.bullseye = 0x25ce;\n  t.c = 0x0063;\n  t.caarmenian = 0x056e;\n  t.cabengali = 0x099a;\n  t.cacute = 0x0107;\n  t.cadeva = 0x091a;\n  t.cagujarati = 0x0a9a;\n  t.cagurmukhi = 0x0a1a;\n  t.calsquare = 0x3388;\n  t.candrabindubengali = 0x0981;\n  t.candrabinducmb = 0x0310;\n  t.candrabindudeva = 0x0901;\n  t.candrabindugujarati = 0x0a81;\n  t.capslock = 0x21ea;\n  t.careof = 0x2105;\n  t.caron = 0x02c7;\n  t.caronbelowcmb = 0x032c;\n  t.caroncmb = 0x030c;\n  t.carriagereturn = 0x21b5;\n  t.cbopomofo = 0x3118;\n  t.ccaron = 0x010d;\n  t.ccedilla = 0x00e7;\n  t.ccedillaacute = 0x1e09;\n  t.ccircle = 0x24d2;\n  t.ccircumflex = 0x0109;\n  t.ccurl = 0x0255;\n  t.cdot = 0x010b;\n  t.cdotaccent = 0x010b;\n  t.cdsquare = 0x33c5;\n  t.cedilla = 0x00b8;\n  t.cedillacmb = 0x0327;\n  t.cent = 0x00a2;\n  t.centigrade = 0x2103;\n  t.centinferior = 0xf6df;\n  t.centmonospace = 0xffe0;\n  t.centoldstyle = 0xf7a2;\n  t.centsuperior = 0xf6e0;\n  t.chaarmenian = 0x0579;\n  t.chabengali = 0x099b;\n  t.chadeva = 0x091b;\n  t.chagujarati = 0x0a9b;\n  t.chagurmukhi = 0x0a1b;\n  t.chbopomofo = 0x3114;\n  t.cheabkhasiancyrillic = 0x04bd;\n  t.checkmark = 0x2713;\n  t.checyrillic = 0x0447;\n  t.chedescenderabkhasiancyrillic = 0x04bf;\n  t.chedescendercyrillic = 0x04b7;\n  t.chedieresiscyrillic = 0x04f5;\n  t.cheharmenian = 0x0573;\n  t.chekhakassiancyrillic = 0x04cc;\n  t.cheverticalstrokecyrillic = 0x04b9;\n  t.chi = 0x03c7;\n  t.chieuchacirclekorean = 0x3277;\n  t.chieuchaparenkorean = 0x3217;\n  t.chieuchcirclekorean = 0x3269;\n  t.chieuchkorean = 0x314a;\n  t.chieuchparenkorean = 0x3209;\n  t.chochangthai = 0x0e0a;\n  t.chochanthai = 0x0e08;\n  t.chochingthai = 0x0e09;\n  t.chochoethai = 0x0e0c;\n  t.chook = 0x0188;\n  t.cieucacirclekorean = 0x3276;\n  t.cieucaparenkorean = 0x3216;\n  t.cieuccirclekorean = 0x3268;\n  t.cieuckorean = 0x3148;\n  t.cieucparenkorean = 0x3208;\n  t.cieucuparenkorean = 0x321c;\n  t.circle = 0x25cb;\n  t.circlecopyrt = 0x00a9;\n  t.circlemultiply = 0x2297;\n  t.circleot = 0x2299;\n  t.circleplus = 0x2295;\n  t.circlepostalmark = 0x3036;\n  t.circlewithlefthalfblack = 0x25d0;\n  t.circlewithrighthalfblack = 0x25d1;\n  t.circumflex = 0x02c6;\n  t.circumflexbelowcmb = 0x032d;\n  t.circumflexcmb = 0x0302;\n  t.clear = 0x2327;\n  t.clickalveolar = 0x01c2;\n  t.clickdental = 0x01c0;\n  t.clicklateral = 0x01c1;\n  t.clickretroflex = 0x01c3;\n  t.club = 0x2663;\n  t.clubsuitblack = 0x2663;\n  t.clubsuitwhite = 0x2667;\n  t.cmcubedsquare = 0x33a4;\n  t.cmonospace = 0xff43;\n  t.cmsquaredsquare = 0x33a0;\n  t.coarmenian = 0x0581;\n  t.colon = 0x003a;\n  t.colonmonetary = 0x20a1;\n  t.colonmonospace = 0xff1a;\n  t.colonsign = 0x20a1;\n  t.colonsmall = 0xfe55;\n  t.colontriangularhalfmod = 0x02d1;\n  t.colontriangularmod = 0x02d0;\n  t.comma = 0x002c;\n  t.commaabovecmb = 0x0313;\n  t.commaaboverightcmb = 0x0315;\n  t.commaaccent = 0xf6c3;\n  t.commaarabic = 0x060c;\n  t.commaarmenian = 0x055d;\n  t.commainferior = 0xf6e1;\n  t.commamonospace = 0xff0c;\n  t.commareversedabovecmb = 0x0314;\n  t.commareversedmod = 0x02bd;\n  t.commasmall = 0xfe50;\n  t.commasuperior = 0xf6e2;\n  t.commaturnedabovecmb = 0x0312;\n  t.commaturnedmod = 0x02bb;\n  t.compass = 0x263c;\n  t.congruent = 0x2245;\n  t.contourintegral = 0x222e;\n  t.control = 0x2303;\n  t.controlACK = 0x0006;\n  t.controlBEL = 0x0007;\n  t.controlBS = 0x0008;\n  t.controlCAN = 0x0018;\n  t.controlCR = 0x000d;\n  t.controlDC1 = 0x0011;\n  t.controlDC2 = 0x0012;\n  t.controlDC3 = 0x0013;\n  t.controlDC4 = 0x0014;\n  t.controlDEL = 0x007f;\n  t.controlDLE = 0x0010;\n  t.controlEM = 0x0019;\n  t.controlENQ = 0x0005;\n  t.controlEOT = 0x0004;\n  t.controlESC = 0x001b;\n  t.controlETB = 0x0017;\n  t.controlETX = 0x0003;\n  t.controlFF = 0x000c;\n  t.controlFS = 0x001c;\n  t.controlGS = 0x001d;\n  t.controlHT = 0x0009;\n  t.controlLF = 0x000a;\n  t.controlNAK = 0x0015;\n  t.controlNULL = 0x0000;\n  t.controlRS = 0x001e;\n  t.controlSI = 0x000f;\n  t.controlSO = 0x000e;\n  t.controlSOT = 0x0002;\n  t.controlSTX = 0x0001;\n  t.controlSUB = 0x001a;\n  t.controlSYN = 0x0016;\n  t.controlUS = 0x001f;\n  t.controlVT = 0x000b;\n  t.copyright = 0x00a9;\n  t.copyrightsans = 0xf8e9;\n  t.copyrightserif = 0xf6d9;\n  t.cornerbracketleft = 0x300c;\n  t.cornerbracketlefthalfwidth = 0xff62;\n  t.cornerbracketleftvertical = 0xfe41;\n  t.cornerbracketright = 0x300d;\n  t.cornerbracketrighthalfwidth = 0xff63;\n  t.cornerbracketrightvertical = 0xfe42;\n  t.corporationsquare = 0x337f;\n  t.cosquare = 0x33c7;\n  t.coverkgsquare = 0x33c6;\n  t.cparen = 0x249e;\n  t.cruzeiro = 0x20a2;\n  t.cstretched = 0x0297;\n  t.curlyand = 0x22cf;\n  t.curlyor = 0x22ce;\n  t.currency = 0x00a4;\n  t.cyrBreve = 0xf6d1;\n  t.cyrFlex = 0xf6d2;\n  t.cyrbreve = 0xf6d4;\n  t.cyrflex = 0xf6d5;\n  t.d = 0x0064;\n  t.daarmenian = 0x0564;\n  t.dabengali = 0x09a6;\n  t.dadarabic = 0x0636;\n  t.dadeva = 0x0926;\n  t.dadfinalarabic = 0xfebe;\n  t.dadinitialarabic = 0xfebf;\n  t.dadmedialarabic = 0xfec0;\n  t.dagesh = 0x05bc;\n  t.dageshhebrew = 0x05bc;\n  t.dagger = 0x2020;\n  t.daggerdbl = 0x2021;\n  t.dagujarati = 0x0aa6;\n  t.dagurmukhi = 0x0a26;\n  t.dahiragana = 0x3060;\n  t.dakatakana = 0x30c0;\n  t.dalarabic = 0x062f;\n  t.dalet = 0x05d3;\n  t.daletdagesh = 0xfb33;\n  t.daletdageshhebrew = 0xfb33;\n  t.dalethebrew = 0x05d3;\n  t.dalfinalarabic = 0xfeaa;\n  t.dammaarabic = 0x064f;\n  t.dammalowarabic = 0x064f;\n  t.dammatanaltonearabic = 0x064c;\n  t.dammatanarabic = 0x064c;\n  t.danda = 0x0964;\n  t.dargahebrew = 0x05a7;\n  t.dargalefthebrew = 0x05a7;\n  t.dasiapneumatacyrilliccmb = 0x0485;\n  t.dblGrave = 0xf6d3;\n  t.dblanglebracketleft = 0x300a;\n  t.dblanglebracketleftvertical = 0xfe3d;\n  t.dblanglebracketright = 0x300b;\n  t.dblanglebracketrightvertical = 0xfe3e;\n  t.dblarchinvertedbelowcmb = 0x032b;\n  t.dblarrowleft = 0x21d4;\n  t.dblarrowright = 0x21d2;\n  t.dbldanda = 0x0965;\n  t.dblgrave = 0xf6d6;\n  t.dblgravecmb = 0x030f;\n  t.dblintegral = 0x222c;\n  t.dbllowline = 0x2017;\n  t.dbllowlinecmb = 0x0333;\n  t.dbloverlinecmb = 0x033f;\n  t.dblprimemod = 0x02ba;\n  t.dblverticalbar = 0x2016;\n  t.dblverticallineabovecmb = 0x030e;\n  t.dbopomofo = 0x3109;\n  t.dbsquare = 0x33c8;\n  t.dcaron = 0x010f;\n  t.dcedilla = 0x1e11;\n  t.dcircle = 0x24d3;\n  t.dcircumflexbelow = 0x1e13;\n  t.dcroat = 0x0111;\n  t.ddabengali = 0x09a1;\n  t.ddadeva = 0x0921;\n  t.ddagujarati = 0x0aa1;\n  t.ddagurmukhi = 0x0a21;\n  t.ddalarabic = 0x0688;\n  t.ddalfinalarabic = 0xfb89;\n  t.dddhadeva = 0x095c;\n  t.ddhabengali = 0x09a2;\n  t.ddhadeva = 0x0922;\n  t.ddhagujarati = 0x0aa2;\n  t.ddhagurmukhi = 0x0a22;\n  t.ddotaccent = 0x1e0b;\n  t.ddotbelow = 0x1e0d;\n  t.decimalseparatorarabic = 0x066b;\n  t.decimalseparatorpersian = 0x066b;\n  t.decyrillic = 0x0434;\n  t.degree = 0x00b0;\n  t.dehihebrew = 0x05ad;\n  t.dehiragana = 0x3067;\n  t.deicoptic = 0x03ef;\n  t.dekatakana = 0x30c7;\n  t.deleteleft = 0x232b;\n  t.deleteright = 0x2326;\n  t.delta = 0x03b4;\n  t.deltaturned = 0x018d;\n  t.denominatorminusonenumeratorbengali = 0x09f8;\n  t.dezh = 0x02a4;\n  t.dhabengali = 0x09a7;\n  t.dhadeva = 0x0927;\n  t.dhagujarati = 0x0aa7;\n  t.dhagurmukhi = 0x0a27;\n  t.dhook = 0x0257;\n  t.dialytikatonos = 0x0385;\n  t.dialytikatonoscmb = 0x0344;\n  t.diamond = 0x2666;\n  t.diamondsuitwhite = 0x2662;\n  t.dieresis = 0x00a8;\n  t.dieresisacute = 0xf6d7;\n  t.dieresisbelowcmb = 0x0324;\n  t.dieresiscmb = 0x0308;\n  t.dieresisgrave = 0xf6d8;\n  t.dieresistonos = 0x0385;\n  t.dihiragana = 0x3062;\n  t.dikatakana = 0x30c2;\n  t.dittomark = 0x3003;\n  t.divide = 0x00f7;\n  t.divides = 0x2223;\n  t.divisionslash = 0x2215;\n  t.djecyrillic = 0x0452;\n  t.dkshade = 0x2593;\n  t.dlinebelow = 0x1e0f;\n  t.dlsquare = 0x3397;\n  t.dmacron = 0x0111;\n  t.dmonospace = 0xff44;\n  t.dnblock = 0x2584;\n  t.dochadathai = 0x0e0e;\n  t.dodekthai = 0x0e14;\n  t.dohiragana = 0x3069;\n  t.dokatakana = 0x30c9;\n  t.dollar = 0x0024;\n  t.dollarinferior = 0xf6e3;\n  t.dollarmonospace = 0xff04;\n  t.dollaroldstyle = 0xf724;\n  t.dollarsmall = 0xfe69;\n  t.dollarsuperior = 0xf6e4;\n  t.dong = 0x20ab;\n  t.dorusquare = 0x3326;\n  t.dotaccent = 0x02d9;\n  t.dotaccentcmb = 0x0307;\n  t.dotbelowcmb = 0x0323;\n  t.dotbelowcomb = 0x0323;\n  t.dotkatakana = 0x30fb;\n  t.dotlessi = 0x0131;\n  t.dotlessj = 0xf6be;\n  t.dotlessjstrokehook = 0x0284;\n  t.dotmath = 0x22c5;\n  t.dottedcircle = 0x25cc;\n  t.doubleyodpatah = 0xfb1f;\n  t.doubleyodpatahhebrew = 0xfb1f;\n  t.downtackbelowcmb = 0x031e;\n  t.downtackmod = 0x02d5;\n  t.dparen = 0x249f;\n  t.dsuperior = 0xf6eb;\n  t.dtail = 0x0256;\n  t.dtopbar = 0x018c;\n  t.duhiragana = 0x3065;\n  t.dukatakana = 0x30c5;\n  t.dz = 0x01f3;\n  t.dzaltone = 0x02a3;\n  t.dzcaron = 0x01c6;\n  t.dzcurl = 0x02a5;\n  t.dzeabkhasiancyrillic = 0x04e1;\n  t.dzecyrillic = 0x0455;\n  t.dzhecyrillic = 0x045f;\n  t.e = 0x0065;\n  t.eacute = 0x00e9;\n  t.earth = 0x2641;\n  t.ebengali = 0x098f;\n  t.ebopomofo = 0x311c;\n  t.ebreve = 0x0115;\n  t.ecandradeva = 0x090d;\n  t.ecandragujarati = 0x0a8d;\n  t.ecandravowelsigndeva = 0x0945;\n  t.ecandravowelsigngujarati = 0x0ac5;\n  t.ecaron = 0x011b;\n  t.ecedillabreve = 0x1e1d;\n  t.echarmenian = 0x0565;\n  t.echyiwnarmenian = 0x0587;\n  t.ecircle = 0x24d4;\n  t.ecircumflex = 0x00ea;\n  t.ecircumflexacute = 0x1ebf;\n  t.ecircumflexbelow = 0x1e19;\n  t.ecircumflexdotbelow = 0x1ec7;\n  t.ecircumflexgrave = 0x1ec1;\n  t.ecircumflexhookabove = 0x1ec3;\n  t.ecircumflextilde = 0x1ec5;\n  t.ecyrillic = 0x0454;\n  t.edblgrave = 0x0205;\n  t.edeva = 0x090f;\n  t.edieresis = 0x00eb;\n  t.edot = 0x0117;\n  t.edotaccent = 0x0117;\n  t.edotbelow = 0x1eb9;\n  t.eegurmukhi = 0x0a0f;\n  t.eematragurmukhi = 0x0a47;\n  t.efcyrillic = 0x0444;\n  t.egrave = 0x00e8;\n  t.egujarati = 0x0a8f;\n  t.eharmenian = 0x0567;\n  t.ehbopomofo = 0x311d;\n  t.ehiragana = 0x3048;\n  t.ehookabove = 0x1ebb;\n  t.eibopomofo = 0x311f;\n  t.eight = 0x0038;\n  t.eightarabic = 0x0668;\n  t.eightbengali = 0x09ee;\n  t.eightcircle = 0x2467;\n  t.eightcircleinversesansserif = 0x2791;\n  t.eightdeva = 0x096e;\n  t.eighteencircle = 0x2471;\n  t.eighteenparen = 0x2485;\n  t.eighteenperiod = 0x2499;\n  t.eightgujarati = 0x0aee;\n  t.eightgurmukhi = 0x0a6e;\n  t.eighthackarabic = 0x0668;\n  t.eighthangzhou = 0x3028;\n  t.eighthnotebeamed = 0x266b;\n  t.eightideographicparen = 0x3227;\n  t.eightinferior = 0x2088;\n  t.eightmonospace = 0xff18;\n  t.eightoldstyle = 0xf738;\n  t.eightparen = 0x247b;\n  t.eightperiod = 0x248f;\n  t.eightpersian = 0x06f8;\n  t.eightroman = 0x2177;\n  t.eightsuperior = 0x2078;\n  t.eightthai = 0x0e58;\n  t.einvertedbreve = 0x0207;\n  t.eiotifiedcyrillic = 0x0465;\n  t.ekatakana = 0x30a8;\n  t.ekatakanahalfwidth = 0xff74;\n  t.ekonkargurmukhi = 0x0a74;\n  t.ekorean = 0x3154;\n  t.elcyrillic = 0x043b;\n  t.element = 0x2208;\n  t.elevencircle = 0x246a;\n  t.elevenparen = 0x247e;\n  t.elevenperiod = 0x2492;\n  t.elevenroman = 0x217a;\n  t.ellipsis = 0x2026;\n  t.ellipsisvertical = 0x22ee;\n  t.emacron = 0x0113;\n  t.emacronacute = 0x1e17;\n  t.emacrongrave = 0x1e15;\n  t.emcyrillic = 0x043c;\n  t.emdash = 0x2014;\n  t.emdashvertical = 0xfe31;\n  t.emonospace = 0xff45;\n  t.emphasismarkarmenian = 0x055b;\n  t.emptyset = 0x2205;\n  t.enbopomofo = 0x3123;\n  t.encyrillic = 0x043d;\n  t.endash = 0x2013;\n  t.endashvertical = 0xfe32;\n  t.endescendercyrillic = 0x04a3;\n  t.eng = 0x014b;\n  t.engbopomofo = 0x3125;\n  t.enghecyrillic = 0x04a5;\n  t.enhookcyrillic = 0x04c8;\n  t.enspace = 0x2002;\n  t.eogonek = 0x0119;\n  t.eokorean = 0x3153;\n  t.eopen = 0x025b;\n  t.eopenclosed = 0x029a;\n  t.eopenreversed = 0x025c;\n  t.eopenreversedclosed = 0x025e;\n  t.eopenreversedhook = 0x025d;\n  t.eparen = 0x24a0;\n  t.epsilon = 0x03b5;\n  t.epsilontonos = 0x03ad;\n  t.equal = 0x003d;\n  t.equalmonospace = 0xff1d;\n  t.equalsmall = 0xfe66;\n  t.equalsuperior = 0x207c;\n  t.equivalence = 0x2261;\n  t.erbopomofo = 0x3126;\n  t.ercyrillic = 0x0440;\n  t.ereversed = 0x0258;\n  t.ereversedcyrillic = 0x044d;\n  t.escyrillic = 0x0441;\n  t.esdescendercyrillic = 0x04ab;\n  t.esh = 0x0283;\n  t.eshcurl = 0x0286;\n  t.eshortdeva = 0x090e;\n  t.eshortvowelsigndeva = 0x0946;\n  t.eshreversedloop = 0x01aa;\n  t.eshsquatreversed = 0x0285;\n  t.esmallhiragana = 0x3047;\n  t.esmallkatakana = 0x30a7;\n  t.esmallkatakanahalfwidth = 0xff6a;\n  t.estimated = 0x212e;\n  t.esuperior = 0xf6ec;\n  t.eta = 0x03b7;\n  t.etarmenian = 0x0568;\n  t.etatonos = 0x03ae;\n  t.eth = 0x00f0;\n  t.etilde = 0x1ebd;\n  t.etildebelow = 0x1e1b;\n  t.etnahtafoukhhebrew = 0x0591;\n  t.etnahtafoukhlefthebrew = 0x0591;\n  t.etnahtahebrew = 0x0591;\n  t.etnahtalefthebrew = 0x0591;\n  t.eturned = 0x01dd;\n  t.eukorean = 0x3161;\n  t.euro = 0x20ac;\n  t.evowelsignbengali = 0x09c7;\n  t.evowelsigndeva = 0x0947;\n  t.evowelsigngujarati = 0x0ac7;\n  t.exclam = 0x0021;\n  t.exclamarmenian = 0x055c;\n  t.exclamdbl = 0x203c;\n  t.exclamdown = 0x00a1;\n  t.exclamdownsmall = 0xf7a1;\n  t.exclammonospace = 0xff01;\n  t.exclamsmall = 0xf721;\n  t.existential = 0x2203;\n  t.ezh = 0x0292;\n  t.ezhcaron = 0x01ef;\n  t.ezhcurl = 0x0293;\n  t.ezhreversed = 0x01b9;\n  t.ezhtail = 0x01ba;\n  t.f = 0x0066;\n  t.fadeva = 0x095e;\n  t.fagurmukhi = 0x0a5e;\n  t.fahrenheit = 0x2109;\n  t.fathaarabic = 0x064e;\n  t.fathalowarabic = 0x064e;\n  t.fathatanarabic = 0x064b;\n  t.fbopomofo = 0x3108;\n  t.fcircle = 0x24d5;\n  t.fdotaccent = 0x1e1f;\n  t.feharabic = 0x0641;\n  t.feharmenian = 0x0586;\n  t.fehfinalarabic = 0xfed2;\n  t.fehinitialarabic = 0xfed3;\n  t.fehmedialarabic = 0xfed4;\n  t.feicoptic = 0x03e5;\n  t.female = 0x2640;\n  t.ff = 0xfb00;\n  t.f_f = 0xfb00;\n  t.ffi = 0xfb03;\n  t.f_f_i = 0xfb03;\n  t.ffl = 0xfb04;\n  t.f_f_l = 0xfb04;\n  t.fi = 0xfb01;\n  t.f_i = 0xfb01;\n  t.fifteencircle = 0x246e;\n  t.fifteenparen = 0x2482;\n  t.fifteenperiod = 0x2496;\n  t.figuredash = 0x2012;\n  t.filledbox = 0x25a0;\n  t.filledrect = 0x25ac;\n  t.finalkaf = 0x05da;\n  t.finalkafdagesh = 0xfb3a;\n  t.finalkafdageshhebrew = 0xfb3a;\n  t.finalkafhebrew = 0x05da;\n  t.finalmem = 0x05dd;\n  t.finalmemhebrew = 0x05dd;\n  t.finalnun = 0x05df;\n  t.finalnunhebrew = 0x05df;\n  t.finalpe = 0x05e3;\n  t.finalpehebrew = 0x05e3;\n  t.finaltsadi = 0x05e5;\n  t.finaltsadihebrew = 0x05e5;\n  t.firsttonechinese = 0x02c9;\n  t.fisheye = 0x25c9;\n  t.fitacyrillic = 0x0473;\n  t.five = 0x0035;\n  t.fivearabic = 0x0665;\n  t.fivebengali = 0x09eb;\n  t.fivecircle = 0x2464;\n  t.fivecircleinversesansserif = 0x278e;\n  t.fivedeva = 0x096b;\n  t.fiveeighths = 0x215d;\n  t.fivegujarati = 0x0aeb;\n  t.fivegurmukhi = 0x0a6b;\n  t.fivehackarabic = 0x0665;\n  t.fivehangzhou = 0x3025;\n  t.fiveideographicparen = 0x3224;\n  t.fiveinferior = 0x2085;\n  t.fivemonospace = 0xff15;\n  t.fiveoldstyle = 0xf735;\n  t.fiveparen = 0x2478;\n  t.fiveperiod = 0x248c;\n  t.fivepersian = 0x06f5;\n  t.fiveroman = 0x2174;\n  t.fivesuperior = 0x2075;\n  t.fivethai = 0x0e55;\n  t.fl = 0xfb02;\n  t.f_l = 0xfb02;\n  t.florin = 0x0192;\n  t.fmonospace = 0xff46;\n  t.fmsquare = 0x3399;\n  t.fofanthai = 0x0e1f;\n  t.fofathai = 0x0e1d;\n  t.fongmanthai = 0x0e4f;\n  t.forall = 0x2200;\n  t.four = 0x0034;\n  t.fourarabic = 0x0664;\n  t.fourbengali = 0x09ea;\n  t.fourcircle = 0x2463;\n  t.fourcircleinversesansserif = 0x278d;\n  t.fourdeva = 0x096a;\n  t.fourgujarati = 0x0aea;\n  t.fourgurmukhi = 0x0a6a;\n  t.fourhackarabic = 0x0664;\n  t.fourhangzhou = 0x3024;\n  t.fourideographicparen = 0x3223;\n  t.fourinferior = 0x2084;\n  t.fourmonospace = 0xff14;\n  t.fournumeratorbengali = 0x09f7;\n  t.fouroldstyle = 0xf734;\n  t.fourparen = 0x2477;\n  t.fourperiod = 0x248b;\n  t.fourpersian = 0x06f4;\n  t.fourroman = 0x2173;\n  t.foursuperior = 0x2074;\n  t.fourteencircle = 0x246d;\n  t.fourteenparen = 0x2481;\n  t.fourteenperiod = 0x2495;\n  t.fourthai = 0x0e54;\n  t.fourthtonechinese = 0x02cb;\n  t.fparen = 0x24a1;\n  t.fraction = 0x2044;\n  t.franc = 0x20a3;\n  t.g = 0x0067;\n  t.gabengali = 0x0997;\n  t.gacute = 0x01f5;\n  t.gadeva = 0x0917;\n  t.gafarabic = 0x06af;\n  t.gaffinalarabic = 0xfb93;\n  t.gafinitialarabic = 0xfb94;\n  t.gafmedialarabic = 0xfb95;\n  t.gagujarati = 0x0a97;\n  t.gagurmukhi = 0x0a17;\n  t.gahiragana = 0x304c;\n  t.gakatakana = 0x30ac;\n  t.gamma = 0x03b3;\n  t.gammalatinsmall = 0x0263;\n  t.gammasuperior = 0x02e0;\n  t.gangiacoptic = 0x03eb;\n  t.gbopomofo = 0x310d;\n  t.gbreve = 0x011f;\n  t.gcaron = 0x01e7;\n  t.gcedilla = 0x0123;\n  t.gcircle = 0x24d6;\n  t.gcircumflex = 0x011d;\n  t.gcommaaccent = 0x0123;\n  t.gdot = 0x0121;\n  t.gdotaccent = 0x0121;\n  t.gecyrillic = 0x0433;\n  t.gehiragana = 0x3052;\n  t.gekatakana = 0x30b2;\n  t.geometricallyequal = 0x2251;\n  t.gereshaccenthebrew = 0x059c;\n  t.gereshhebrew = 0x05f3;\n  t.gereshmuqdamhebrew = 0x059d;\n  t.germandbls = 0x00df;\n  t.gershayimaccenthebrew = 0x059e;\n  t.gershayimhebrew = 0x05f4;\n  t.getamark = 0x3013;\n  t.ghabengali = 0x0998;\n  t.ghadarmenian = 0x0572;\n  t.ghadeva = 0x0918;\n  t.ghagujarati = 0x0a98;\n  t.ghagurmukhi = 0x0a18;\n  t.ghainarabic = 0x063a;\n  t.ghainfinalarabic = 0xfece;\n  t.ghaininitialarabic = 0xfecf;\n  t.ghainmedialarabic = 0xfed0;\n  t.ghemiddlehookcyrillic = 0x0495;\n  t.ghestrokecyrillic = 0x0493;\n  t.gheupturncyrillic = 0x0491;\n  t.ghhadeva = 0x095a;\n  t.ghhagurmukhi = 0x0a5a;\n  t.ghook = 0x0260;\n  t.ghzsquare = 0x3393;\n  t.gihiragana = 0x304e;\n  t.gikatakana = 0x30ae;\n  t.gimarmenian = 0x0563;\n  t.gimel = 0x05d2;\n  t.gimeldagesh = 0xfb32;\n  t.gimeldageshhebrew = 0xfb32;\n  t.gimelhebrew = 0x05d2;\n  t.gjecyrillic = 0x0453;\n  t.glottalinvertedstroke = 0x01be;\n  t.glottalstop = 0x0294;\n  t.glottalstopinverted = 0x0296;\n  t.glottalstopmod = 0x02c0;\n  t.glottalstopreversed = 0x0295;\n  t.glottalstopreversedmod = 0x02c1;\n  t.glottalstopreversedsuperior = 0x02e4;\n  t.glottalstopstroke = 0x02a1;\n  t.glottalstopstrokereversed = 0x02a2;\n  t.gmacron = 0x1e21;\n  t.gmonospace = 0xff47;\n  t.gohiragana = 0x3054;\n  t.gokatakana = 0x30b4;\n  t.gparen = 0x24a2;\n  t.gpasquare = 0x33ac;\n  t.gradient = 0x2207;\n  t.grave = 0x0060;\n  t.gravebelowcmb = 0x0316;\n  t.gravecmb = 0x0300;\n  t.gravecomb = 0x0300;\n  t.gravedeva = 0x0953;\n  t.gravelowmod = 0x02ce;\n  t.gravemonospace = 0xff40;\n  t.gravetonecmb = 0x0340;\n  t.greater = 0x003e;\n  t.greaterequal = 0x2265;\n  t.greaterequalorless = 0x22db;\n  t.greatermonospace = 0xff1e;\n  t.greaterorequivalent = 0x2273;\n  t.greaterorless = 0x2277;\n  t.greateroverequal = 0x2267;\n  t.greatersmall = 0xfe65;\n  t.gscript = 0x0261;\n  t.gstroke = 0x01e5;\n  t.guhiragana = 0x3050;\n  t.guillemotleft = 0x00ab;\n  t.guillemotright = 0x00bb;\n  t.guilsinglleft = 0x2039;\n  t.guilsinglright = 0x203a;\n  t.gukatakana = 0x30b0;\n  t.guramusquare = 0x3318;\n  t.gysquare = 0x33c9;\n  t.h = 0x0068;\n  t.haabkhasiancyrillic = 0x04a9;\n  t.haaltonearabic = 0x06c1;\n  t.habengali = 0x09b9;\n  t.hadescendercyrillic = 0x04b3;\n  t.hadeva = 0x0939;\n  t.hagujarati = 0x0ab9;\n  t.hagurmukhi = 0x0a39;\n  t.haharabic = 0x062d;\n  t.hahfinalarabic = 0xfea2;\n  t.hahinitialarabic = 0xfea3;\n  t.hahiragana = 0x306f;\n  t.hahmedialarabic = 0xfea4;\n  t.haitusquare = 0x332a;\n  t.hakatakana = 0x30cf;\n  t.hakatakanahalfwidth = 0xff8a;\n  t.halantgurmukhi = 0x0a4d;\n  t.hamzaarabic = 0x0621;\n  t.hamzalowarabic = 0x0621;\n  t.hangulfiller = 0x3164;\n  t.hardsigncyrillic = 0x044a;\n  t.harpoonleftbarbup = 0x21bc;\n  t.harpoonrightbarbup = 0x21c0;\n  t.hasquare = 0x33ca;\n  t.hatafpatah = 0x05b2;\n  t.hatafpatah16 = 0x05b2;\n  t.hatafpatah23 = 0x05b2;\n  t.hatafpatah2f = 0x05b2;\n  t.hatafpatahhebrew = 0x05b2;\n  t.hatafpatahnarrowhebrew = 0x05b2;\n  t.hatafpatahquarterhebrew = 0x05b2;\n  t.hatafpatahwidehebrew = 0x05b2;\n  t.hatafqamats = 0x05b3;\n  t.hatafqamats1b = 0x05b3;\n  t.hatafqamats28 = 0x05b3;\n  t.hatafqamats34 = 0x05b3;\n  t.hatafqamatshebrew = 0x05b3;\n  t.hatafqamatsnarrowhebrew = 0x05b3;\n  t.hatafqamatsquarterhebrew = 0x05b3;\n  t.hatafqamatswidehebrew = 0x05b3;\n  t.hatafsegol = 0x05b1;\n  t.hatafsegol17 = 0x05b1;\n  t.hatafsegol24 = 0x05b1;\n  t.hatafsegol30 = 0x05b1;\n  t.hatafsegolhebrew = 0x05b1;\n  t.hatafsegolnarrowhebrew = 0x05b1;\n  t.hatafsegolquarterhebrew = 0x05b1;\n  t.hatafsegolwidehebrew = 0x05b1;\n  t.hbar = 0x0127;\n  t.hbopomofo = 0x310f;\n  t.hbrevebelow = 0x1e2b;\n  t.hcedilla = 0x1e29;\n  t.hcircle = 0x24d7;\n  t.hcircumflex = 0x0125;\n  t.hdieresis = 0x1e27;\n  t.hdotaccent = 0x1e23;\n  t.hdotbelow = 0x1e25;\n  t.he = 0x05d4;\n  t.heart = 0x2665;\n  t.heartsuitblack = 0x2665;\n  t.heartsuitwhite = 0x2661;\n  t.hedagesh = 0xfb34;\n  t.hedageshhebrew = 0xfb34;\n  t.hehaltonearabic = 0x06c1;\n  t.heharabic = 0x0647;\n  t.hehebrew = 0x05d4;\n  t.hehfinalaltonearabic = 0xfba7;\n  t.hehfinalalttwoarabic = 0xfeea;\n  t.hehfinalarabic = 0xfeea;\n  t.hehhamzaabovefinalarabic = 0xfba5;\n  t.hehhamzaaboveisolatedarabic = 0xfba4;\n  t.hehinitialaltonearabic = 0xfba8;\n  t.hehinitialarabic = 0xfeeb;\n  t.hehiragana = 0x3078;\n  t.hehmedialaltonearabic = 0xfba9;\n  t.hehmedialarabic = 0xfeec;\n  t.heiseierasquare = 0x337b;\n  t.hekatakana = 0x30d8;\n  t.hekatakanahalfwidth = 0xff8d;\n  t.hekutaarusquare = 0x3336;\n  t.henghook = 0x0267;\n  t.herutusquare = 0x3339;\n  t.het = 0x05d7;\n  t.hethebrew = 0x05d7;\n  t.hhook = 0x0266;\n  t.hhooksuperior = 0x02b1;\n  t.hieuhacirclekorean = 0x327b;\n  t.hieuhaparenkorean = 0x321b;\n  t.hieuhcirclekorean = 0x326d;\n  t.hieuhkorean = 0x314e;\n  t.hieuhparenkorean = 0x320d;\n  t.hihiragana = 0x3072;\n  t.hikatakana = 0x30d2;\n  t.hikatakanahalfwidth = 0xff8b;\n  t.hiriq = 0x05b4;\n  t.hiriq14 = 0x05b4;\n  t.hiriq21 = 0x05b4;\n  t.hiriq2d = 0x05b4;\n  t.hiriqhebrew = 0x05b4;\n  t.hiriqnarrowhebrew = 0x05b4;\n  t.hiriqquarterhebrew = 0x05b4;\n  t.hiriqwidehebrew = 0x05b4;\n  t.hlinebelow = 0x1e96;\n  t.hmonospace = 0xff48;\n  t.hoarmenian = 0x0570;\n  t.hohipthai = 0x0e2b;\n  t.hohiragana = 0x307b;\n  t.hokatakana = 0x30db;\n  t.hokatakanahalfwidth = 0xff8e;\n  t.holam = 0x05b9;\n  t.holam19 = 0x05b9;\n  t.holam26 = 0x05b9;\n  t.holam32 = 0x05b9;\n  t.holamhebrew = 0x05b9;\n  t.holamnarrowhebrew = 0x05b9;\n  t.holamquarterhebrew = 0x05b9;\n  t.holamwidehebrew = 0x05b9;\n  t.honokhukthai = 0x0e2e;\n  t.hookabovecomb = 0x0309;\n  t.hookcmb = 0x0309;\n  t.hookpalatalizedbelowcmb = 0x0321;\n  t.hookretroflexbelowcmb = 0x0322;\n  t.hoonsquare = 0x3342;\n  t.horicoptic = 0x03e9;\n  t.horizontalbar = 0x2015;\n  t.horncmb = 0x031b;\n  t.hotsprings = 0x2668;\n  t.house = 0x2302;\n  t.hparen = 0x24a3;\n  t.hsuperior = 0x02b0;\n  t.hturned = 0x0265;\n  t.huhiragana = 0x3075;\n  t.huiitosquare = 0x3333;\n  t.hukatakana = 0x30d5;\n  t.hukatakanahalfwidth = 0xff8c;\n  t.hungarumlaut = 0x02dd;\n  t.hungarumlautcmb = 0x030b;\n  t.hv = 0x0195;\n  t.hyphen = 0x002d;\n  t.hypheninferior = 0xf6e5;\n  t.hyphenmonospace = 0xff0d;\n  t.hyphensmall = 0xfe63;\n  t.hyphensuperior = 0xf6e6;\n  t.hyphentwo = 0x2010;\n  t.i = 0x0069;\n  t.iacute = 0x00ed;\n  t.iacyrillic = 0x044f;\n  t.ibengali = 0x0987;\n  t.ibopomofo = 0x3127;\n  t.ibreve = 0x012d;\n  t.icaron = 0x01d0;\n  t.icircle = 0x24d8;\n  t.icircumflex = 0x00ee;\n  t.icyrillic = 0x0456;\n  t.idblgrave = 0x0209;\n  t.ideographearthcircle = 0x328f;\n  t.ideographfirecircle = 0x328b;\n  t.ideographicallianceparen = 0x323f;\n  t.ideographiccallparen = 0x323a;\n  t.ideographiccentrecircle = 0x32a5;\n  t.ideographicclose = 0x3006;\n  t.ideographiccomma = 0x3001;\n  t.ideographiccommaleft = 0xff64;\n  t.ideographiccongratulationparen = 0x3237;\n  t.ideographiccorrectcircle = 0x32a3;\n  t.ideographicearthparen = 0x322f;\n  t.ideographicenterpriseparen = 0x323d;\n  t.ideographicexcellentcircle = 0x329d;\n  t.ideographicfestivalparen = 0x3240;\n  t.ideographicfinancialcircle = 0x3296;\n  t.ideographicfinancialparen = 0x3236;\n  t.ideographicfireparen = 0x322b;\n  t.ideographichaveparen = 0x3232;\n  t.ideographichighcircle = 0x32a4;\n  t.ideographiciterationmark = 0x3005;\n  t.ideographiclaborcircle = 0x3298;\n  t.ideographiclaborparen = 0x3238;\n  t.ideographicleftcircle = 0x32a7;\n  t.ideographiclowcircle = 0x32a6;\n  t.ideographicmedicinecircle = 0x32a9;\n  t.ideographicmetalparen = 0x322e;\n  t.ideographicmoonparen = 0x322a;\n  t.ideographicnameparen = 0x3234;\n  t.ideographicperiod = 0x3002;\n  t.ideographicprintcircle = 0x329e;\n  t.ideographicreachparen = 0x3243;\n  t.ideographicrepresentparen = 0x3239;\n  t.ideographicresourceparen = 0x323e;\n  t.ideographicrightcircle = 0x32a8;\n  t.ideographicsecretcircle = 0x3299;\n  t.ideographicselfparen = 0x3242;\n  t.ideographicsocietyparen = 0x3233;\n  t.ideographicspace = 0x3000;\n  t.ideographicspecialparen = 0x3235;\n  t.ideographicstockparen = 0x3231;\n  t.ideographicstudyparen = 0x323b;\n  t.ideographicsunparen = 0x3230;\n  t.ideographicsuperviseparen = 0x323c;\n  t.ideographicwaterparen = 0x322c;\n  t.ideographicwoodparen = 0x322d;\n  t.ideographiczero = 0x3007;\n  t.ideographmetalcircle = 0x328e;\n  t.ideographmooncircle = 0x328a;\n  t.ideographnamecircle = 0x3294;\n  t.ideographsuncircle = 0x3290;\n  t.ideographwatercircle = 0x328c;\n  t.ideographwoodcircle = 0x328d;\n  t.ideva = 0x0907;\n  t.idieresis = 0x00ef;\n  t.idieresisacute = 0x1e2f;\n  t.idieresiscyrillic = 0x04e5;\n  t.idotbelow = 0x1ecb;\n  t.iebrevecyrillic = 0x04d7;\n  t.iecyrillic = 0x0435;\n  t.ieungacirclekorean = 0x3275;\n  t.ieungaparenkorean = 0x3215;\n  t.ieungcirclekorean = 0x3267;\n  t.ieungkorean = 0x3147;\n  t.ieungparenkorean = 0x3207;\n  t.igrave = 0x00ec;\n  t.igujarati = 0x0a87;\n  t.igurmukhi = 0x0a07;\n  t.ihiragana = 0x3044;\n  t.ihookabove = 0x1ec9;\n  t.iibengali = 0x0988;\n  t.iicyrillic = 0x0438;\n  t.iideva = 0x0908;\n  t.iigujarati = 0x0a88;\n  t.iigurmukhi = 0x0a08;\n  t.iimatragurmukhi = 0x0a40;\n  t.iinvertedbreve = 0x020b;\n  t.iishortcyrillic = 0x0439;\n  t.iivowelsignbengali = 0x09c0;\n  t.iivowelsigndeva = 0x0940;\n  t.iivowelsigngujarati = 0x0ac0;\n  t.ij = 0x0133;\n  t.ikatakana = 0x30a4;\n  t.ikatakanahalfwidth = 0xff72;\n  t.ikorean = 0x3163;\n  t.ilde = 0x02dc;\n  t.iluyhebrew = 0x05ac;\n  t.imacron = 0x012b;\n  t.imacroncyrillic = 0x04e3;\n  t.imageorapproximatelyequal = 0x2253;\n  t.imatragurmukhi = 0x0a3f;\n  t.imonospace = 0xff49;\n  t.increment = 0x2206;\n  t.infinity = 0x221e;\n  t.iniarmenian = 0x056b;\n  t.integral = 0x222b;\n  t.integralbottom = 0x2321;\n  t.integralbt = 0x2321;\n  t.integralex = 0xf8f5;\n  t.integraltop = 0x2320;\n  t.integraltp = 0x2320;\n  t.intersection = 0x2229;\n  t.intisquare = 0x3305;\n  t.invbullet = 0x25d8;\n  t.invcircle = 0x25d9;\n  t.invsmileface = 0x263b;\n  t.iocyrillic = 0x0451;\n  t.iogonek = 0x012f;\n  t.iota = 0x03b9;\n  t.iotadieresis = 0x03ca;\n  t.iotadieresistonos = 0x0390;\n  t.iotalatin = 0x0269;\n  t.iotatonos = 0x03af;\n  t.iparen = 0x24a4;\n  t.irigurmukhi = 0x0a72;\n  t.ismallhiragana = 0x3043;\n  t.ismallkatakana = 0x30a3;\n  t.ismallkatakanahalfwidth = 0xff68;\n  t.issharbengali = 0x09fa;\n  t.istroke = 0x0268;\n  t.isuperior = 0xf6ed;\n  t.iterationhiragana = 0x309d;\n  t.iterationkatakana = 0x30fd;\n  t.itilde = 0x0129;\n  t.itildebelow = 0x1e2d;\n  t.iubopomofo = 0x3129;\n  t.iucyrillic = 0x044e;\n  t.ivowelsignbengali = 0x09bf;\n  t.ivowelsigndeva = 0x093f;\n  t.ivowelsigngujarati = 0x0abf;\n  t.izhitsacyrillic = 0x0475;\n  t.izhitsadblgravecyrillic = 0x0477;\n  t.j = 0x006a;\n  t.jaarmenian = 0x0571;\n  t.jabengali = 0x099c;\n  t.jadeva = 0x091c;\n  t.jagujarati = 0x0a9c;\n  t.jagurmukhi = 0x0a1c;\n  t.jbopomofo = 0x3110;\n  t.jcaron = 0x01f0;\n  t.jcircle = 0x24d9;\n  t.jcircumflex = 0x0135;\n  t.jcrossedtail = 0x029d;\n  t.jdotlessstroke = 0x025f;\n  t.jecyrillic = 0x0458;\n  t.jeemarabic = 0x062c;\n  t.jeemfinalarabic = 0xfe9e;\n  t.jeeminitialarabic = 0xfe9f;\n  t.jeemmedialarabic = 0xfea0;\n  t.jeharabic = 0x0698;\n  t.jehfinalarabic = 0xfb8b;\n  t.jhabengali = 0x099d;\n  t.jhadeva = 0x091d;\n  t.jhagujarati = 0x0a9d;\n  t.jhagurmukhi = 0x0a1d;\n  t.jheharmenian = 0x057b;\n  t.jis = 0x3004;\n  t.jmonospace = 0xff4a;\n  t.jparen = 0x24a5;\n  t.jsuperior = 0x02b2;\n  t.k = 0x006b;\n  t.kabashkircyrillic = 0x04a1;\n  t.kabengali = 0x0995;\n  t.kacute = 0x1e31;\n  t.kacyrillic = 0x043a;\n  t.kadescendercyrillic = 0x049b;\n  t.kadeva = 0x0915;\n  t.kaf = 0x05db;\n  t.kafarabic = 0x0643;\n  t.kafdagesh = 0xfb3b;\n  t.kafdageshhebrew = 0xfb3b;\n  t.kaffinalarabic = 0xfeda;\n  t.kafhebrew = 0x05db;\n  t.kafinitialarabic = 0xfedb;\n  t.kafmedialarabic = 0xfedc;\n  t.kafrafehebrew = 0xfb4d;\n  t.kagujarati = 0x0a95;\n  t.kagurmukhi = 0x0a15;\n  t.kahiragana = 0x304b;\n  t.kahookcyrillic = 0x04c4;\n  t.kakatakana = 0x30ab;\n  t.kakatakanahalfwidth = 0xff76;\n  t.kappa = 0x03ba;\n  t.kappasymbolgreek = 0x03f0;\n  t.kapyeounmieumkorean = 0x3171;\n  t.kapyeounphieuphkorean = 0x3184;\n  t.kapyeounpieupkorean = 0x3178;\n  t.kapyeounssangpieupkorean = 0x3179;\n  t.karoriisquare = 0x330d;\n  t.kashidaautoarabic = 0x0640;\n  t.kashidaautonosidebearingarabic = 0x0640;\n  t.kasmallkatakana = 0x30f5;\n  t.kasquare = 0x3384;\n  t.kasraarabic = 0x0650;\n  t.kasratanarabic = 0x064d;\n  t.kastrokecyrillic = 0x049f;\n  t.katahiraprolongmarkhalfwidth = 0xff70;\n  t.kaverticalstrokecyrillic = 0x049d;\n  t.kbopomofo = 0x310e;\n  t.kcalsquare = 0x3389;\n  t.kcaron = 0x01e9;\n  t.kcedilla = 0x0137;\n  t.kcircle = 0x24da;\n  t.kcommaaccent = 0x0137;\n  t.kdotbelow = 0x1e33;\n  t.keharmenian = 0x0584;\n  t.kehiragana = 0x3051;\n  t.kekatakana = 0x30b1;\n  t.kekatakanahalfwidth = 0xff79;\n  t.kenarmenian = 0x056f;\n  t.kesmallkatakana = 0x30f6;\n  t.kgreenlandic = 0x0138;\n  t.khabengali = 0x0996;\n  t.khacyrillic = 0x0445;\n  t.khadeva = 0x0916;\n  t.khagujarati = 0x0a96;\n  t.khagurmukhi = 0x0a16;\n  t.khaharabic = 0x062e;\n  t.khahfinalarabic = 0xfea6;\n  t.khahinitialarabic = 0xfea7;\n  t.khahmedialarabic = 0xfea8;\n  t.kheicoptic = 0x03e7;\n  t.khhadeva = 0x0959;\n  t.khhagurmukhi = 0x0a59;\n  t.khieukhacirclekorean = 0x3278;\n  t.khieukhaparenkorean = 0x3218;\n  t.khieukhcirclekorean = 0x326a;\n  t.khieukhkorean = 0x314b;\n  t.khieukhparenkorean = 0x320a;\n  t.khokhaithai = 0x0e02;\n  t.khokhonthai = 0x0e05;\n  t.khokhuatthai = 0x0e03;\n  t.khokhwaithai = 0x0e04;\n  t.khomutthai = 0x0e5b;\n  t.khook = 0x0199;\n  t.khorakhangthai = 0x0e06;\n  t.khzsquare = 0x3391;\n  t.kihiragana = 0x304d;\n  t.kikatakana = 0x30ad;\n  t.kikatakanahalfwidth = 0xff77;\n  t.kiroguramusquare = 0x3315;\n  t.kiromeetorusquare = 0x3316;\n  t.kirosquare = 0x3314;\n  t.kiyeokacirclekorean = 0x326e;\n  t.kiyeokaparenkorean = 0x320e;\n  t.kiyeokcirclekorean = 0x3260;\n  t.kiyeokkorean = 0x3131;\n  t.kiyeokparenkorean = 0x3200;\n  t.kiyeoksioskorean = 0x3133;\n  t.kjecyrillic = 0x045c;\n  t.klinebelow = 0x1e35;\n  t.klsquare = 0x3398;\n  t.kmcubedsquare = 0x33a6;\n  t.kmonospace = 0xff4b;\n  t.kmsquaredsquare = 0x33a2;\n  t.kohiragana = 0x3053;\n  t.kohmsquare = 0x33c0;\n  t.kokaithai = 0x0e01;\n  t.kokatakana = 0x30b3;\n  t.kokatakanahalfwidth = 0xff7a;\n  t.kooposquare = 0x331e;\n  t.koppacyrillic = 0x0481;\n  t.koreanstandardsymbol = 0x327f;\n  t.koroniscmb = 0x0343;\n  t.kparen = 0x24a6;\n  t.kpasquare = 0x33aa;\n  t.ksicyrillic = 0x046f;\n  t.ktsquare = 0x33cf;\n  t.kturned = 0x029e;\n  t.kuhiragana = 0x304f;\n  t.kukatakana = 0x30af;\n  t.kukatakanahalfwidth = 0xff78;\n  t.kvsquare = 0x33b8;\n  t.kwsquare = 0x33be;\n  t.l = 0x006c;\n  t.labengali = 0x09b2;\n  t.lacute = 0x013a;\n  t.ladeva = 0x0932;\n  t.lagujarati = 0x0ab2;\n  t.lagurmukhi = 0x0a32;\n  t.lakkhangyaothai = 0x0e45;\n  t.lamaleffinalarabic = 0xfefc;\n  t.lamalefhamzaabovefinalarabic = 0xfef8;\n  t.lamalefhamzaaboveisolatedarabic = 0xfef7;\n  t.lamalefhamzabelowfinalarabic = 0xfefa;\n  t.lamalefhamzabelowisolatedarabic = 0xfef9;\n  t.lamalefisolatedarabic = 0xfefb;\n  t.lamalefmaddaabovefinalarabic = 0xfef6;\n  t.lamalefmaddaaboveisolatedarabic = 0xfef5;\n  t.lamarabic = 0x0644;\n  t.lambda = 0x03bb;\n  t.lambdastroke = 0x019b;\n  t.lamed = 0x05dc;\n  t.lameddagesh = 0xfb3c;\n  t.lameddageshhebrew = 0xfb3c;\n  t.lamedhebrew = 0x05dc;\n  t.lamfinalarabic = 0xfede;\n  t.lamhahinitialarabic = 0xfcca;\n  t.laminitialarabic = 0xfedf;\n  t.lamjeeminitialarabic = 0xfcc9;\n  t.lamkhahinitialarabic = 0xfccb;\n  t.lamlamhehisolatedarabic = 0xfdf2;\n  t.lammedialarabic = 0xfee0;\n  t.lammeemhahinitialarabic = 0xfd88;\n  t.lammeeminitialarabic = 0xfccc;\n  t.largecircle = 0x25ef;\n  t.lbar = 0x019a;\n  t.lbelt = 0x026c;\n  t.lbopomofo = 0x310c;\n  t.lcaron = 0x013e;\n  t.lcedilla = 0x013c;\n  t.lcircle = 0x24db;\n  t.lcircumflexbelow = 0x1e3d;\n  t.lcommaaccent = 0x013c;\n  t.ldot = 0x0140;\n  t.ldotaccent = 0x0140;\n  t.ldotbelow = 0x1e37;\n  t.ldotbelowmacron = 0x1e39;\n  t.leftangleabovecmb = 0x031a;\n  t.lefttackbelowcmb = 0x0318;\n  t.less = 0x003c;\n  t.lessequal = 0x2264;\n  t.lessequalorgreater = 0x22da;\n  t.lessmonospace = 0xff1c;\n  t.lessorequivalent = 0x2272;\n  t.lessorgreater = 0x2276;\n  t.lessoverequal = 0x2266;\n  t.lesssmall = 0xfe64;\n  t.lezh = 0x026e;\n  t.lfblock = 0x258c;\n  t.lhookretroflex = 0x026d;\n  t.lira = 0x20a4;\n  t.liwnarmenian = 0x056c;\n  t.lj = 0x01c9;\n  t.ljecyrillic = 0x0459;\n  t.ll = 0xf6c0;\n  t.lladeva = 0x0933;\n  t.llagujarati = 0x0ab3;\n  t.llinebelow = 0x1e3b;\n  t.llladeva = 0x0934;\n  t.llvocalicbengali = 0x09e1;\n  t.llvocalicdeva = 0x0961;\n  t.llvocalicvowelsignbengali = 0x09e3;\n  t.llvocalicvowelsigndeva = 0x0963;\n  t.lmiddletilde = 0x026b;\n  t.lmonospace = 0xff4c;\n  t.lmsquare = 0x33d0;\n  t.lochulathai = 0x0e2c;\n  t.logicaland = 0x2227;\n  t.logicalnot = 0x00ac;\n  t.logicalnotreversed = 0x2310;\n  t.logicalor = 0x2228;\n  t.lolingthai = 0x0e25;\n  t.longs = 0x017f;\n  t.lowlinecenterline = 0xfe4e;\n  t.lowlinecmb = 0x0332;\n  t.lowlinedashed = 0xfe4d;\n  t.lozenge = 0x25ca;\n  t.lparen = 0x24a7;\n  t.lslash = 0x0142;\n  t.lsquare = 0x2113;\n  t.lsuperior = 0xf6ee;\n  t.ltshade = 0x2591;\n  t.luthai = 0x0e26;\n  t.lvocalicbengali = 0x098c;\n  t.lvocalicdeva = 0x090c;\n  t.lvocalicvowelsignbengali = 0x09e2;\n  t.lvocalicvowelsigndeva = 0x0962;\n  t.lxsquare = 0x33d3;\n  t.m = 0x006d;\n  t.mabengali = 0x09ae;\n  t.macron = 0x00af;\n  t.macronbelowcmb = 0x0331;\n  t.macroncmb = 0x0304;\n  t.macronlowmod = 0x02cd;\n  t.macronmonospace = 0xffe3;\n  t.macute = 0x1e3f;\n  t.madeva = 0x092e;\n  t.magujarati = 0x0aae;\n  t.magurmukhi = 0x0a2e;\n  t.mahapakhhebrew = 0x05a4;\n  t.mahapakhlefthebrew = 0x05a4;\n  t.mahiragana = 0x307e;\n  t.maichattawalowleftthai = 0xf895;\n  t.maichattawalowrightthai = 0xf894;\n  t.maichattawathai = 0x0e4b;\n  t.maichattawaupperleftthai = 0xf893;\n  t.maieklowleftthai = 0xf88c;\n  t.maieklowrightthai = 0xf88b;\n  t.maiekthai = 0x0e48;\n  t.maiekupperleftthai = 0xf88a;\n  t.maihanakatleftthai = 0xf884;\n  t.maihanakatthai = 0x0e31;\n  t.maitaikhuleftthai = 0xf889;\n  t.maitaikhuthai = 0x0e47;\n  t.maitholowleftthai = 0xf88f;\n  t.maitholowrightthai = 0xf88e;\n  t.maithothai = 0x0e49;\n  t.maithoupperleftthai = 0xf88d;\n  t.maitrilowleftthai = 0xf892;\n  t.maitrilowrightthai = 0xf891;\n  t.maitrithai = 0x0e4a;\n  t.maitriupperleftthai = 0xf890;\n  t.maiyamokthai = 0x0e46;\n  t.makatakana = 0x30de;\n  t.makatakanahalfwidth = 0xff8f;\n  t.male = 0x2642;\n  t.mansyonsquare = 0x3347;\n  t.maqafhebrew = 0x05be;\n  t.mars = 0x2642;\n  t.masoracirclehebrew = 0x05af;\n  t.masquare = 0x3383;\n  t.mbopomofo = 0x3107;\n  t.mbsquare = 0x33d4;\n  t.mcircle = 0x24dc;\n  t.mcubedsquare = 0x33a5;\n  t.mdotaccent = 0x1e41;\n  t.mdotbelow = 0x1e43;\n  t.meemarabic = 0x0645;\n  t.meemfinalarabic = 0xfee2;\n  t.meeminitialarabic = 0xfee3;\n  t.meemmedialarabic = 0xfee4;\n  t.meemmeeminitialarabic = 0xfcd1;\n  t.meemmeemisolatedarabic = 0xfc48;\n  t.meetorusquare = 0x334d;\n  t.mehiragana = 0x3081;\n  t.meizierasquare = 0x337e;\n  t.mekatakana = 0x30e1;\n  t.mekatakanahalfwidth = 0xff92;\n  t.mem = 0x05de;\n  t.memdagesh = 0xfb3e;\n  t.memdageshhebrew = 0xfb3e;\n  t.memhebrew = 0x05de;\n  t.menarmenian = 0x0574;\n  t.merkhahebrew = 0x05a5;\n  t.merkhakefulahebrew = 0x05a6;\n  t.merkhakefulalefthebrew = 0x05a6;\n  t.merkhalefthebrew = 0x05a5;\n  t.mhook = 0x0271;\n  t.mhzsquare = 0x3392;\n  t.middledotkatakanahalfwidth = 0xff65;\n  t.middot = 0x00b7;\n  t.mieumacirclekorean = 0x3272;\n  t.mieumaparenkorean = 0x3212;\n  t.mieumcirclekorean = 0x3264;\n  t.mieumkorean = 0x3141;\n  t.mieumpansioskorean = 0x3170;\n  t.mieumparenkorean = 0x3204;\n  t.mieumpieupkorean = 0x316e;\n  t.mieumsioskorean = 0x316f;\n  t.mihiragana = 0x307f;\n  t.mikatakana = 0x30df;\n  t.mikatakanahalfwidth = 0xff90;\n  t.minus = 0x2212;\n  t.minusbelowcmb = 0x0320;\n  t.minuscircle = 0x2296;\n  t.minusmod = 0x02d7;\n  t.minusplus = 0x2213;\n  t.minute = 0x2032;\n  t.miribaarusquare = 0x334a;\n  t.mirisquare = 0x3349;\n  t.mlonglegturned = 0x0270;\n  t.mlsquare = 0x3396;\n  t.mmcubedsquare = 0x33a3;\n  t.mmonospace = 0xff4d;\n  t.mmsquaredsquare = 0x339f;\n  t.mohiragana = 0x3082;\n  t.mohmsquare = 0x33c1;\n  t.mokatakana = 0x30e2;\n  t.mokatakanahalfwidth = 0xff93;\n  t.molsquare = 0x33d6;\n  t.momathai = 0x0e21;\n  t.moverssquare = 0x33a7;\n  t.moverssquaredsquare = 0x33a8;\n  t.mparen = 0x24a8;\n  t.mpasquare = 0x33ab;\n  t.mssquare = 0x33b3;\n  t.msuperior = 0xf6ef;\n  t.mturned = 0x026f;\n  t.mu = 0x00b5;\n  t.mu1 = 0x00b5;\n  t.muasquare = 0x3382;\n  t.muchgreater = 0x226b;\n  t.muchless = 0x226a;\n  t.mufsquare = 0x338c;\n  t.mugreek = 0x03bc;\n  t.mugsquare = 0x338d;\n  t.muhiragana = 0x3080;\n  t.mukatakana = 0x30e0;\n  t.mukatakanahalfwidth = 0xff91;\n  t.mulsquare = 0x3395;\n  t.multiply = 0x00d7;\n  t.mumsquare = 0x339b;\n  t.munahhebrew = 0x05a3;\n  t.munahlefthebrew = 0x05a3;\n  t.musicalnote = 0x266a;\n  t.musicalnotedbl = 0x266b;\n  t.musicflatsign = 0x266d;\n  t.musicsharpsign = 0x266f;\n  t.mussquare = 0x33b2;\n  t.muvsquare = 0x33b6;\n  t.muwsquare = 0x33bc;\n  t.mvmegasquare = 0x33b9;\n  t.mvsquare = 0x33b7;\n  t.mwmegasquare = 0x33bf;\n  t.mwsquare = 0x33bd;\n  t.n = 0x006e;\n  t.nabengali = 0x09a8;\n  t.nabla = 0x2207;\n  t.nacute = 0x0144;\n  t.nadeva = 0x0928;\n  t.nagujarati = 0x0aa8;\n  t.nagurmukhi = 0x0a28;\n  t.nahiragana = 0x306a;\n  t.nakatakana = 0x30ca;\n  t.nakatakanahalfwidth = 0xff85;\n  t.napostrophe = 0x0149;\n  t.nasquare = 0x3381;\n  t.nbopomofo = 0x310b;\n  t.nbspace = 0x00a0;\n  t.ncaron = 0x0148;\n  t.ncedilla = 0x0146;\n  t.ncircle = 0x24dd;\n  t.ncircumflexbelow = 0x1e4b;\n  t.ncommaaccent = 0x0146;\n  t.ndotaccent = 0x1e45;\n  t.ndotbelow = 0x1e47;\n  t.nehiragana = 0x306d;\n  t.nekatakana = 0x30cd;\n  t.nekatakanahalfwidth = 0xff88;\n  t.newsheqelsign = 0x20aa;\n  t.nfsquare = 0x338b;\n  t.ngabengali = 0x0999;\n  t.ngadeva = 0x0919;\n  t.ngagujarati = 0x0a99;\n  t.ngagurmukhi = 0x0a19;\n  t.ngonguthai = 0x0e07;\n  t.nhiragana = 0x3093;\n  t.nhookleft = 0x0272;\n  t.nhookretroflex = 0x0273;\n  t.nieunacirclekorean = 0x326f;\n  t.nieunaparenkorean = 0x320f;\n  t.nieuncieuckorean = 0x3135;\n  t.nieuncirclekorean = 0x3261;\n  t.nieunhieuhkorean = 0x3136;\n  t.nieunkorean = 0x3134;\n  t.nieunpansioskorean = 0x3168;\n  t.nieunparenkorean = 0x3201;\n  t.nieunsioskorean = 0x3167;\n  t.nieuntikeutkorean = 0x3166;\n  t.nihiragana = 0x306b;\n  t.nikatakana = 0x30cb;\n  t.nikatakanahalfwidth = 0xff86;\n  t.nikhahitleftthai = 0xf899;\n  t.nikhahitthai = 0x0e4d;\n  t.nine = 0x0039;\n  t.ninearabic = 0x0669;\n  t.ninebengali = 0x09ef;\n  t.ninecircle = 0x2468;\n  t.ninecircleinversesansserif = 0x2792;\n  t.ninedeva = 0x096f;\n  t.ninegujarati = 0x0aef;\n  t.ninegurmukhi = 0x0a6f;\n  t.ninehackarabic = 0x0669;\n  t.ninehangzhou = 0x3029;\n  t.nineideographicparen = 0x3228;\n  t.nineinferior = 0x2089;\n  t.ninemonospace = 0xff19;\n  t.nineoldstyle = 0xf739;\n  t.nineparen = 0x247c;\n  t.nineperiod = 0x2490;\n  t.ninepersian = 0x06f9;\n  t.nineroman = 0x2178;\n  t.ninesuperior = 0x2079;\n  t.nineteencircle = 0x2472;\n  t.nineteenparen = 0x2486;\n  t.nineteenperiod = 0x249a;\n  t.ninethai = 0x0e59;\n  t.nj = 0x01cc;\n  t.njecyrillic = 0x045a;\n  t.nkatakana = 0x30f3;\n  t.nkatakanahalfwidth = 0xff9d;\n  t.nlegrightlong = 0x019e;\n  t.nlinebelow = 0x1e49;\n  t.nmonospace = 0xff4e;\n  t.nmsquare = 0x339a;\n  t.nnabengali = 0x09a3;\n  t.nnadeva = 0x0923;\n  t.nnagujarati = 0x0aa3;\n  t.nnagurmukhi = 0x0a23;\n  t.nnnadeva = 0x0929;\n  t.nohiragana = 0x306e;\n  t.nokatakana = 0x30ce;\n  t.nokatakanahalfwidth = 0xff89;\n  t.nonbreakingspace = 0x00a0;\n  t.nonenthai = 0x0e13;\n  t.nonuthai = 0x0e19;\n  t.noonarabic = 0x0646;\n  t.noonfinalarabic = 0xfee6;\n  t.noonghunnaarabic = 0x06ba;\n  t.noonghunnafinalarabic = 0xfb9f;\n  t.nooninitialarabic = 0xfee7;\n  t.noonjeeminitialarabic = 0xfcd2;\n  t.noonjeemisolatedarabic = 0xfc4b;\n  t.noonmedialarabic = 0xfee8;\n  t.noonmeeminitialarabic = 0xfcd5;\n  t.noonmeemisolatedarabic = 0xfc4e;\n  t.noonnoonfinalarabic = 0xfc8d;\n  t.notcontains = 0x220c;\n  t.notelement = 0x2209;\n  t.notelementof = 0x2209;\n  t.notequal = 0x2260;\n  t.notgreater = 0x226f;\n  t.notgreaternorequal = 0x2271;\n  t.notgreaternorless = 0x2279;\n  t.notidentical = 0x2262;\n  t.notless = 0x226e;\n  t.notlessnorequal = 0x2270;\n  t.notparallel = 0x2226;\n  t.notprecedes = 0x2280;\n  t.notsubset = 0x2284;\n  t.notsucceeds = 0x2281;\n  t.notsuperset = 0x2285;\n  t.nowarmenian = 0x0576;\n  t.nparen = 0x24a9;\n  t.nssquare = 0x33b1;\n  t.nsuperior = 0x207f;\n  t.ntilde = 0x00f1;\n  t.nu = 0x03bd;\n  t.nuhiragana = 0x306c;\n  t.nukatakana = 0x30cc;\n  t.nukatakanahalfwidth = 0xff87;\n  t.nuktabengali = 0x09bc;\n  t.nuktadeva = 0x093c;\n  t.nuktagujarati = 0x0abc;\n  t.nuktagurmukhi = 0x0a3c;\n  t.numbersign = 0x0023;\n  t.numbersignmonospace = 0xff03;\n  t.numbersignsmall = 0xfe5f;\n  t.numeralsigngreek = 0x0374;\n  t.numeralsignlowergreek = 0x0375;\n  t.numero = 0x2116;\n  t.nun = 0x05e0;\n  t.nundagesh = 0xfb40;\n  t.nundageshhebrew = 0xfb40;\n  t.nunhebrew = 0x05e0;\n  t.nvsquare = 0x33b5;\n  t.nwsquare = 0x33bb;\n  t.nyabengali = 0x099e;\n  t.nyadeva = 0x091e;\n  t.nyagujarati = 0x0a9e;\n  t.nyagurmukhi = 0x0a1e;\n  t.o = 0x006f;\n  t.oacute = 0x00f3;\n  t.oangthai = 0x0e2d;\n  t.obarred = 0x0275;\n  t.obarredcyrillic = 0x04e9;\n  t.obarreddieresiscyrillic = 0x04eb;\n  t.obengali = 0x0993;\n  t.obopomofo = 0x311b;\n  t.obreve = 0x014f;\n  t.ocandradeva = 0x0911;\n  t.ocandragujarati = 0x0a91;\n  t.ocandravowelsigndeva = 0x0949;\n  t.ocandravowelsigngujarati = 0x0ac9;\n  t.ocaron = 0x01d2;\n  t.ocircle = 0x24de;\n  t.ocircumflex = 0x00f4;\n  t.ocircumflexacute = 0x1ed1;\n  t.ocircumflexdotbelow = 0x1ed9;\n  t.ocircumflexgrave = 0x1ed3;\n  t.ocircumflexhookabove = 0x1ed5;\n  t.ocircumflextilde = 0x1ed7;\n  t.ocyrillic = 0x043e;\n  t.odblacute = 0x0151;\n  t.odblgrave = 0x020d;\n  t.odeva = 0x0913;\n  t.odieresis = 0x00f6;\n  t.odieresiscyrillic = 0x04e7;\n  t.odotbelow = 0x1ecd;\n  t.oe = 0x0153;\n  t.oekorean = 0x315a;\n  t.ogonek = 0x02db;\n  t.ogonekcmb = 0x0328;\n  t.ograve = 0x00f2;\n  t.ogujarati = 0x0a93;\n  t.oharmenian = 0x0585;\n  t.ohiragana = 0x304a;\n  t.ohookabove = 0x1ecf;\n  t.ohorn = 0x01a1;\n  t.ohornacute = 0x1edb;\n  t.ohorndotbelow = 0x1ee3;\n  t.ohorngrave = 0x1edd;\n  t.ohornhookabove = 0x1edf;\n  t.ohorntilde = 0x1ee1;\n  t.ohungarumlaut = 0x0151;\n  t.oi = 0x01a3;\n  t.oinvertedbreve = 0x020f;\n  t.okatakana = 0x30aa;\n  t.okatakanahalfwidth = 0xff75;\n  t.okorean = 0x3157;\n  t.olehebrew = 0x05ab;\n  t.omacron = 0x014d;\n  t.omacronacute = 0x1e53;\n  t.omacrongrave = 0x1e51;\n  t.omdeva = 0x0950;\n  t.omega = 0x03c9;\n  t.omega1 = 0x03d6;\n  t.omegacyrillic = 0x0461;\n  t.omegalatinclosed = 0x0277;\n  t.omegaroundcyrillic = 0x047b;\n  t.omegatitlocyrillic = 0x047d;\n  t.omegatonos = 0x03ce;\n  t.omgujarati = 0x0ad0;\n  t.omicron = 0x03bf;\n  t.omicrontonos = 0x03cc;\n  t.omonospace = 0xff4f;\n  t.one = 0x0031;\n  t.onearabic = 0x0661;\n  t.onebengali = 0x09e7;\n  t.onecircle = 0x2460;\n  t.onecircleinversesansserif = 0x278a;\n  t.onedeva = 0x0967;\n  t.onedotenleader = 0x2024;\n  t.oneeighth = 0x215b;\n  t.onefitted = 0xf6dc;\n  t.onegujarati = 0x0ae7;\n  t.onegurmukhi = 0x0a67;\n  t.onehackarabic = 0x0661;\n  t.onehalf = 0x00bd;\n  t.onehangzhou = 0x3021;\n  t.oneideographicparen = 0x3220;\n  t.oneinferior = 0x2081;\n  t.onemonospace = 0xff11;\n  t.onenumeratorbengali = 0x09f4;\n  t.oneoldstyle = 0xf731;\n  t.oneparen = 0x2474;\n  t.oneperiod = 0x2488;\n  t.onepersian = 0x06f1;\n  t.onequarter = 0x00bc;\n  t.oneroman = 0x2170;\n  t.onesuperior = 0x00b9;\n  t.onethai = 0x0e51;\n  t.onethird = 0x2153;\n  t.oogonek = 0x01eb;\n  t.oogonekmacron = 0x01ed;\n  t.oogurmukhi = 0x0a13;\n  t.oomatragurmukhi = 0x0a4b;\n  t.oopen = 0x0254;\n  t.oparen = 0x24aa;\n  t.openbullet = 0x25e6;\n  t.option = 0x2325;\n  t.ordfeminine = 0x00aa;\n  t.ordmasculine = 0x00ba;\n  t.orthogonal = 0x221f;\n  t.oshortdeva = 0x0912;\n  t.oshortvowelsigndeva = 0x094a;\n  t.oslash = 0x00f8;\n  t.oslashacute = 0x01ff;\n  t.osmallhiragana = 0x3049;\n  t.osmallkatakana = 0x30a9;\n  t.osmallkatakanahalfwidth = 0xff6b;\n  t.ostrokeacute = 0x01ff;\n  t.osuperior = 0xf6f0;\n  t.otcyrillic = 0x047f;\n  t.otilde = 0x00f5;\n  t.otildeacute = 0x1e4d;\n  t.otildedieresis = 0x1e4f;\n  t.oubopomofo = 0x3121;\n  t.overline = 0x203e;\n  t.overlinecenterline = 0xfe4a;\n  t.overlinecmb = 0x0305;\n  t.overlinedashed = 0xfe49;\n  t.overlinedblwavy = 0xfe4c;\n  t.overlinewavy = 0xfe4b;\n  t.overscore = 0x00af;\n  t.ovowelsignbengali = 0x09cb;\n  t.ovowelsigndeva = 0x094b;\n  t.ovowelsigngujarati = 0x0acb;\n  t.p = 0x0070;\n  t.paampssquare = 0x3380;\n  t.paasentosquare = 0x332b;\n  t.pabengali = 0x09aa;\n  t.pacute = 0x1e55;\n  t.padeva = 0x092a;\n  t.pagedown = 0x21df;\n  t.pageup = 0x21de;\n  t.pagujarati = 0x0aaa;\n  t.pagurmukhi = 0x0a2a;\n  t.pahiragana = 0x3071;\n  t.paiyannoithai = 0x0e2f;\n  t.pakatakana = 0x30d1;\n  t.palatalizationcyrilliccmb = 0x0484;\n  t.palochkacyrillic = 0x04c0;\n  t.pansioskorean = 0x317f;\n  t.paragraph = 0x00b6;\n  t.parallel = 0x2225;\n  t.parenleft = 0x0028;\n  t.parenleftaltonearabic = 0xfd3e;\n  t.parenleftbt = 0xf8ed;\n  t.parenleftex = 0xf8ec;\n  t.parenleftinferior = 0x208d;\n  t.parenleftmonospace = 0xff08;\n  t.parenleftsmall = 0xfe59;\n  t.parenleftsuperior = 0x207d;\n  t.parenlefttp = 0xf8eb;\n  t.parenleftvertical = 0xfe35;\n  t.parenright = 0x0029;\n  t.parenrightaltonearabic = 0xfd3f;\n  t.parenrightbt = 0xf8f8;\n  t.parenrightex = 0xf8f7;\n  t.parenrightinferior = 0x208e;\n  t.parenrightmonospace = 0xff09;\n  t.parenrightsmall = 0xfe5a;\n  t.parenrightsuperior = 0x207e;\n  t.parenrighttp = 0xf8f6;\n  t.parenrightvertical = 0xfe36;\n  t.partialdiff = 0x2202;\n  t.paseqhebrew = 0x05c0;\n  t.pashtahebrew = 0x0599;\n  t.pasquare = 0x33a9;\n  t.patah = 0x05b7;\n  t.patah11 = 0x05b7;\n  t.patah1d = 0x05b7;\n  t.patah2a = 0x05b7;\n  t.patahhebrew = 0x05b7;\n  t.patahnarrowhebrew = 0x05b7;\n  t.patahquarterhebrew = 0x05b7;\n  t.patahwidehebrew = 0x05b7;\n  t.pazerhebrew = 0x05a1;\n  t.pbopomofo = 0x3106;\n  t.pcircle = 0x24df;\n  t.pdotaccent = 0x1e57;\n  t.pe = 0x05e4;\n  t.pecyrillic = 0x043f;\n  t.pedagesh = 0xfb44;\n  t.pedageshhebrew = 0xfb44;\n  t.peezisquare = 0x333b;\n  t.pefinaldageshhebrew = 0xfb43;\n  t.peharabic = 0x067e;\n  t.peharmenian = 0x057a;\n  t.pehebrew = 0x05e4;\n  t.pehfinalarabic = 0xfb57;\n  t.pehinitialarabic = 0xfb58;\n  t.pehiragana = 0x307a;\n  t.pehmedialarabic = 0xfb59;\n  t.pekatakana = 0x30da;\n  t.pemiddlehookcyrillic = 0x04a7;\n  t.perafehebrew = 0xfb4e;\n  t.percent = 0x0025;\n  t.percentarabic = 0x066a;\n  t.percentmonospace = 0xff05;\n  t.percentsmall = 0xfe6a;\n  t.period = 0x002e;\n  t.periodarmenian = 0x0589;\n  t.periodcentered = 0x00b7;\n  t.periodhalfwidth = 0xff61;\n  t.periodinferior = 0xf6e7;\n  t.periodmonospace = 0xff0e;\n  t.periodsmall = 0xfe52;\n  t.periodsuperior = 0xf6e8;\n  t.perispomenigreekcmb = 0x0342;\n  t.perpendicular = 0x22a5;\n  t.perthousand = 0x2030;\n  t.peseta = 0x20a7;\n  t.pfsquare = 0x338a;\n  t.phabengali = 0x09ab;\n  t.phadeva = 0x092b;\n  t.phagujarati = 0x0aab;\n  t.phagurmukhi = 0x0a2b;\n  t.phi = 0x03c6;\n  t.phi1 = 0x03d5;\n  t.phieuphacirclekorean = 0x327a;\n  t.phieuphaparenkorean = 0x321a;\n  t.phieuphcirclekorean = 0x326c;\n  t.phieuphkorean = 0x314d;\n  t.phieuphparenkorean = 0x320c;\n  t.philatin = 0x0278;\n  t.phinthuthai = 0x0e3a;\n  t.phisymbolgreek = 0x03d5;\n  t.phook = 0x01a5;\n  t.phophanthai = 0x0e1e;\n  t.phophungthai = 0x0e1c;\n  t.phosamphaothai = 0x0e20;\n  t.pi = 0x03c0;\n  t.pieupacirclekorean = 0x3273;\n  t.pieupaparenkorean = 0x3213;\n  t.pieupcieuckorean = 0x3176;\n  t.pieupcirclekorean = 0x3265;\n  t.pieupkiyeokkorean = 0x3172;\n  t.pieupkorean = 0x3142;\n  t.pieupparenkorean = 0x3205;\n  t.pieupsioskiyeokkorean = 0x3174;\n  t.pieupsioskorean = 0x3144;\n  t.pieupsiostikeutkorean = 0x3175;\n  t.pieupthieuthkorean = 0x3177;\n  t.pieuptikeutkorean = 0x3173;\n  t.pihiragana = 0x3074;\n  t.pikatakana = 0x30d4;\n  t.pisymbolgreek = 0x03d6;\n  t.piwrarmenian = 0x0583;\n  t.planckover2pi = 0x210f;\n  t.planckover2pi1 = 0x210f;\n  t.plus = 0x002b;\n  t.plusbelowcmb = 0x031f;\n  t.pluscircle = 0x2295;\n  t.plusminus = 0x00b1;\n  t.plusmod = 0x02d6;\n  t.plusmonospace = 0xff0b;\n  t.plussmall = 0xfe62;\n  t.plussuperior = 0x207a;\n  t.pmonospace = 0xff50;\n  t.pmsquare = 0x33d8;\n  t.pohiragana = 0x307d;\n  t.pointingindexdownwhite = 0x261f;\n  t.pointingindexleftwhite = 0x261c;\n  t.pointingindexrightwhite = 0x261e;\n  t.pointingindexupwhite = 0x261d;\n  t.pokatakana = 0x30dd;\n  t.poplathai = 0x0e1b;\n  t.postalmark = 0x3012;\n  t.postalmarkface = 0x3020;\n  t.pparen = 0x24ab;\n  t.precedes = 0x227a;\n  t.prescription = 0x211e;\n  t.primemod = 0x02b9;\n  t.primereversed = 0x2035;\n  t.product = 0x220f;\n  t.projective = 0x2305;\n  t.prolongedkana = 0x30fc;\n  t.propellor = 0x2318;\n  t.propersubset = 0x2282;\n  t.propersuperset = 0x2283;\n  t.proportion = 0x2237;\n  t.proportional = 0x221d;\n  t.psi = 0x03c8;\n  t.psicyrillic = 0x0471;\n  t.psilipneumatacyrilliccmb = 0x0486;\n  t.pssquare = 0x33b0;\n  t.puhiragana = 0x3077;\n  t.pukatakana = 0x30d7;\n  t.pvsquare = 0x33b4;\n  t.pwsquare = 0x33ba;\n  t.q = 0x0071;\n  t.qadeva = 0x0958;\n  t.qadmahebrew = 0x05a8;\n  t.qafarabic = 0x0642;\n  t.qaffinalarabic = 0xfed6;\n  t.qafinitialarabic = 0xfed7;\n  t.qafmedialarabic = 0xfed8;\n  t.qamats = 0x05b8;\n  t.qamats10 = 0x05b8;\n  t.qamats1a = 0x05b8;\n  t.qamats1c = 0x05b8;\n  t.qamats27 = 0x05b8;\n  t.qamats29 = 0x05b8;\n  t.qamats33 = 0x05b8;\n  t.qamatsde = 0x05b8;\n  t.qamatshebrew = 0x05b8;\n  t.qamatsnarrowhebrew = 0x05b8;\n  t.qamatsqatanhebrew = 0x05b8;\n  t.qamatsqatannarrowhebrew = 0x05b8;\n  t.qamatsqatanquarterhebrew = 0x05b8;\n  t.qamatsqatanwidehebrew = 0x05b8;\n  t.qamatsquarterhebrew = 0x05b8;\n  t.qamatswidehebrew = 0x05b8;\n  t.qarneyparahebrew = 0x059f;\n  t.qbopomofo = 0x3111;\n  t.qcircle = 0x24e0;\n  t.qhook = 0x02a0;\n  t.qmonospace = 0xff51;\n  t.qof = 0x05e7;\n  t.qofdagesh = 0xfb47;\n  t.qofdageshhebrew = 0xfb47;\n  t.qofhebrew = 0x05e7;\n  t.qparen = 0x24ac;\n  t.quarternote = 0x2669;\n  t.qubuts = 0x05bb;\n  t.qubuts18 = 0x05bb;\n  t.qubuts25 = 0x05bb;\n  t.qubuts31 = 0x05bb;\n  t.qubutshebrew = 0x05bb;\n  t.qubutsnarrowhebrew = 0x05bb;\n  t.qubutsquarterhebrew = 0x05bb;\n  t.qubutswidehebrew = 0x05bb;\n  t.question = 0x003f;\n  t.questionarabic = 0x061f;\n  t.questionarmenian = 0x055e;\n  t.questiondown = 0x00bf;\n  t.questiondownsmall = 0xf7bf;\n  t.questiongreek = 0x037e;\n  t.questionmonospace = 0xff1f;\n  t.questionsmall = 0xf73f;\n  t.quotedbl = 0x0022;\n  t.quotedblbase = 0x201e;\n  t.quotedblleft = 0x201c;\n  t.quotedblmonospace = 0xff02;\n  t.quotedblprime = 0x301e;\n  t.quotedblprimereversed = 0x301d;\n  t.quotedblright = 0x201d;\n  t.quoteleft = 0x2018;\n  t.quoteleftreversed = 0x201b;\n  t.quotereversed = 0x201b;\n  t.quoteright = 0x2019;\n  t.quoterightn = 0x0149;\n  t.quotesinglbase = 0x201a;\n  t.quotesingle = 0x0027;\n  t.quotesinglemonospace = 0xff07;\n  t.r = 0x0072;\n  t.raarmenian = 0x057c;\n  t.rabengali = 0x09b0;\n  t.racute = 0x0155;\n  t.radeva = 0x0930;\n  t.radical = 0x221a;\n  t.radicalex = 0xf8e5;\n  t.radoverssquare = 0x33ae;\n  t.radoverssquaredsquare = 0x33af;\n  t.radsquare = 0x33ad;\n  t.rafe = 0x05bf;\n  t.rafehebrew = 0x05bf;\n  t.ragujarati = 0x0ab0;\n  t.ragurmukhi = 0x0a30;\n  t.rahiragana = 0x3089;\n  t.rakatakana = 0x30e9;\n  t.rakatakanahalfwidth = 0xff97;\n  t.ralowerdiagonalbengali = 0x09f1;\n  t.ramiddlediagonalbengali = 0x09f0;\n  t.ramshorn = 0x0264;\n  t.ratio = 0x2236;\n  t.rbopomofo = 0x3116;\n  t.rcaron = 0x0159;\n  t.rcedilla = 0x0157;\n  t.rcircle = 0x24e1;\n  t.rcommaaccent = 0x0157;\n  t.rdblgrave = 0x0211;\n  t.rdotaccent = 0x1e59;\n  t.rdotbelow = 0x1e5b;\n  t.rdotbelowmacron = 0x1e5d;\n  t.referencemark = 0x203b;\n  t.reflexsubset = 0x2286;\n  t.reflexsuperset = 0x2287;\n  t.registered = 0x00ae;\n  t.registersans = 0xf8e8;\n  t.registerserif = 0xf6da;\n  t.reharabic = 0x0631;\n  t.reharmenian = 0x0580;\n  t.rehfinalarabic = 0xfeae;\n  t.rehiragana = 0x308c;\n  t.rekatakana = 0x30ec;\n  t.rekatakanahalfwidth = 0xff9a;\n  t.resh = 0x05e8;\n  t.reshdageshhebrew = 0xfb48;\n  t.reshhebrew = 0x05e8;\n  t.reversedtilde = 0x223d;\n  t.reviahebrew = 0x0597;\n  t.reviamugrashhebrew = 0x0597;\n  t.revlogicalnot = 0x2310;\n  t.rfishhook = 0x027e;\n  t.rfishhookreversed = 0x027f;\n  t.rhabengali = 0x09dd;\n  t.rhadeva = 0x095d;\n  t.rho = 0x03c1;\n  t.rhook = 0x027d;\n  t.rhookturned = 0x027b;\n  t.rhookturnedsuperior = 0x02b5;\n  t.rhosymbolgreek = 0x03f1;\n  t.rhotichookmod = 0x02de;\n  t.rieulacirclekorean = 0x3271;\n  t.rieulaparenkorean = 0x3211;\n  t.rieulcirclekorean = 0x3263;\n  t.rieulhieuhkorean = 0x3140;\n  t.rieulkiyeokkorean = 0x313a;\n  t.rieulkiyeoksioskorean = 0x3169;\n  t.rieulkorean = 0x3139;\n  t.rieulmieumkorean = 0x313b;\n  t.rieulpansioskorean = 0x316c;\n  t.rieulparenkorean = 0x3203;\n  t.rieulphieuphkorean = 0x313f;\n  t.rieulpieupkorean = 0x313c;\n  t.rieulpieupsioskorean = 0x316b;\n  t.rieulsioskorean = 0x313d;\n  t.rieulthieuthkorean = 0x313e;\n  t.rieultikeutkorean = 0x316a;\n  t.rieulyeorinhieuhkorean = 0x316d;\n  t.rightangle = 0x221f;\n  t.righttackbelowcmb = 0x0319;\n  t.righttriangle = 0x22bf;\n  t.rihiragana = 0x308a;\n  t.rikatakana = 0x30ea;\n  t.rikatakanahalfwidth = 0xff98;\n  t.ring = 0x02da;\n  t.ringbelowcmb = 0x0325;\n  t.ringcmb = 0x030a;\n  t.ringhalfleft = 0x02bf;\n  t.ringhalfleftarmenian = 0x0559;\n  t.ringhalfleftbelowcmb = 0x031c;\n  t.ringhalfleftcentered = 0x02d3;\n  t.ringhalfright = 0x02be;\n  t.ringhalfrightbelowcmb = 0x0339;\n  t.ringhalfrightcentered = 0x02d2;\n  t.rinvertedbreve = 0x0213;\n  t.rittorusquare = 0x3351;\n  t.rlinebelow = 0x1e5f;\n  t.rlongleg = 0x027c;\n  t.rlonglegturned = 0x027a;\n  t.rmonospace = 0xff52;\n  t.rohiragana = 0x308d;\n  t.rokatakana = 0x30ed;\n  t.rokatakanahalfwidth = 0xff9b;\n  t.roruathai = 0x0e23;\n  t.rparen = 0x24ad;\n  t.rrabengali = 0x09dc;\n  t.rradeva = 0x0931;\n  t.rragurmukhi = 0x0a5c;\n  t.rreharabic = 0x0691;\n  t.rrehfinalarabic = 0xfb8d;\n  t.rrvocalicbengali = 0x09e0;\n  t.rrvocalicdeva = 0x0960;\n  t.rrvocalicgujarati = 0x0ae0;\n  t.rrvocalicvowelsignbengali = 0x09c4;\n  t.rrvocalicvowelsigndeva = 0x0944;\n  t.rrvocalicvowelsigngujarati = 0x0ac4;\n  t.rsuperior = 0xf6f1;\n  t.rtblock = 0x2590;\n  t.rturned = 0x0279;\n  t.rturnedsuperior = 0x02b4;\n  t.ruhiragana = 0x308b;\n  t.rukatakana = 0x30eb;\n  t.rukatakanahalfwidth = 0xff99;\n  t.rupeemarkbengali = 0x09f2;\n  t.rupeesignbengali = 0x09f3;\n  t.rupiah = 0xf6dd;\n  t.ruthai = 0x0e24;\n  t.rvocalicbengali = 0x098b;\n  t.rvocalicdeva = 0x090b;\n  t.rvocalicgujarati = 0x0a8b;\n  t.rvocalicvowelsignbengali = 0x09c3;\n  t.rvocalicvowelsigndeva = 0x0943;\n  t.rvocalicvowelsigngujarati = 0x0ac3;\n  t.s = 0x0073;\n  t.sabengali = 0x09b8;\n  t.sacute = 0x015b;\n  t.sacutedotaccent = 0x1e65;\n  t.sadarabic = 0x0635;\n  t.sadeva = 0x0938;\n  t.sadfinalarabic = 0xfeba;\n  t.sadinitialarabic = 0xfebb;\n  t.sadmedialarabic = 0xfebc;\n  t.sagujarati = 0x0ab8;\n  t.sagurmukhi = 0x0a38;\n  t.sahiragana = 0x3055;\n  t.sakatakana = 0x30b5;\n  t.sakatakanahalfwidth = 0xff7b;\n  t.sallallahoualayhewasallamarabic = 0xfdfa;\n  t.samekh = 0x05e1;\n  t.samekhdagesh = 0xfb41;\n  t.samekhdageshhebrew = 0xfb41;\n  t.samekhhebrew = 0x05e1;\n  t.saraaathai = 0x0e32;\n  t.saraaethai = 0x0e41;\n  t.saraaimaimalaithai = 0x0e44;\n  t.saraaimaimuanthai = 0x0e43;\n  t.saraamthai = 0x0e33;\n  t.saraathai = 0x0e30;\n  t.saraethai = 0x0e40;\n  t.saraiileftthai = 0xf886;\n  t.saraiithai = 0x0e35;\n  t.saraileftthai = 0xf885;\n  t.saraithai = 0x0e34;\n  t.saraothai = 0x0e42;\n  t.saraueeleftthai = 0xf888;\n  t.saraueethai = 0x0e37;\n  t.saraueleftthai = 0xf887;\n  t.sarauethai = 0x0e36;\n  t.sarauthai = 0x0e38;\n  t.sarauuthai = 0x0e39;\n  t.sbopomofo = 0x3119;\n  t.scaron = 0x0161;\n  t.scarondotaccent = 0x1e67;\n  t.scedilla = 0x015f;\n  t.schwa = 0x0259;\n  t.schwacyrillic = 0x04d9;\n  t.schwadieresiscyrillic = 0x04db;\n  t.schwahook = 0x025a;\n  t.scircle = 0x24e2;\n  t.scircumflex = 0x015d;\n  t.scommaaccent = 0x0219;\n  t.sdotaccent = 0x1e61;\n  t.sdotbelow = 0x1e63;\n  t.sdotbelowdotaccent = 0x1e69;\n  t.seagullbelowcmb = 0x033c;\n  t.second = 0x2033;\n  t.secondtonechinese = 0x02ca;\n  t.section = 0x00a7;\n  t.seenarabic = 0x0633;\n  t.seenfinalarabic = 0xfeb2;\n  t.seeninitialarabic = 0xfeb3;\n  t.seenmedialarabic = 0xfeb4;\n  t.segol = 0x05b6;\n  t.segol13 = 0x05b6;\n  t.segol1f = 0x05b6;\n  t.segol2c = 0x05b6;\n  t.segolhebrew = 0x05b6;\n  t.segolnarrowhebrew = 0x05b6;\n  t.segolquarterhebrew = 0x05b6;\n  t.segoltahebrew = 0x0592;\n  t.segolwidehebrew = 0x05b6;\n  t.seharmenian = 0x057d;\n  t.sehiragana = 0x305b;\n  t.sekatakana = 0x30bb;\n  t.sekatakanahalfwidth = 0xff7e;\n  t.semicolon = 0x003b;\n  t.semicolonarabic = 0x061b;\n  t.semicolonmonospace = 0xff1b;\n  t.semicolonsmall = 0xfe54;\n  t.semivoicedmarkkana = 0x309c;\n  t.semivoicedmarkkanahalfwidth = 0xff9f;\n  t.sentisquare = 0x3322;\n  t.sentosquare = 0x3323;\n  t.seven = 0x0037;\n  t.sevenarabic = 0x0667;\n  t.sevenbengali = 0x09ed;\n  t.sevencircle = 0x2466;\n  t.sevencircleinversesansserif = 0x2790;\n  t.sevendeva = 0x096d;\n  t.seveneighths = 0x215e;\n  t.sevengujarati = 0x0aed;\n  t.sevengurmukhi = 0x0a6d;\n  t.sevenhackarabic = 0x0667;\n  t.sevenhangzhou = 0x3027;\n  t.sevenideographicparen = 0x3226;\n  t.seveninferior = 0x2087;\n  t.sevenmonospace = 0xff17;\n  t.sevenoldstyle = 0xf737;\n  t.sevenparen = 0x247a;\n  t.sevenperiod = 0x248e;\n  t.sevenpersian = 0x06f7;\n  t.sevenroman = 0x2176;\n  t.sevensuperior = 0x2077;\n  t.seventeencircle = 0x2470;\n  t.seventeenparen = 0x2484;\n  t.seventeenperiod = 0x2498;\n  t.seventhai = 0x0e57;\n  t.sfthyphen = 0x00ad;\n  t.shaarmenian = 0x0577;\n  t.shabengali = 0x09b6;\n  t.shacyrillic = 0x0448;\n  t.shaddaarabic = 0x0651;\n  t.shaddadammaarabic = 0xfc61;\n  t.shaddadammatanarabic = 0xfc5e;\n  t.shaddafathaarabic = 0xfc60;\n  t.shaddakasraarabic = 0xfc62;\n  t.shaddakasratanarabic = 0xfc5f;\n  t.shade = 0x2592;\n  t.shadedark = 0x2593;\n  t.shadelight = 0x2591;\n  t.shademedium = 0x2592;\n  t.shadeva = 0x0936;\n  t.shagujarati = 0x0ab6;\n  t.shagurmukhi = 0x0a36;\n  t.shalshelethebrew = 0x0593;\n  t.shbopomofo = 0x3115;\n  t.shchacyrillic = 0x0449;\n  t.sheenarabic = 0x0634;\n  t.sheenfinalarabic = 0xfeb6;\n  t.sheeninitialarabic = 0xfeb7;\n  t.sheenmedialarabic = 0xfeb8;\n  t.sheicoptic = 0x03e3;\n  t.sheqel = 0x20aa;\n  t.sheqelhebrew = 0x20aa;\n  t.sheva = 0x05b0;\n  t.sheva115 = 0x05b0;\n  t.sheva15 = 0x05b0;\n  t.sheva22 = 0x05b0;\n  t.sheva2e = 0x05b0;\n  t.shevahebrew = 0x05b0;\n  t.shevanarrowhebrew = 0x05b0;\n  t.shevaquarterhebrew = 0x05b0;\n  t.shevawidehebrew = 0x05b0;\n  t.shhacyrillic = 0x04bb;\n  t.shimacoptic = 0x03ed;\n  t.shin = 0x05e9;\n  t.shindagesh = 0xfb49;\n  t.shindageshhebrew = 0xfb49;\n  t.shindageshshindot = 0xfb2c;\n  t.shindageshshindothebrew = 0xfb2c;\n  t.shindageshsindot = 0xfb2d;\n  t.shindageshsindothebrew = 0xfb2d;\n  t.shindothebrew = 0x05c1;\n  t.shinhebrew = 0x05e9;\n  t.shinshindot = 0xfb2a;\n  t.shinshindothebrew = 0xfb2a;\n  t.shinsindot = 0xfb2b;\n  t.shinsindothebrew = 0xfb2b;\n  t.shook = 0x0282;\n  t.sigma = 0x03c3;\n  t.sigma1 = 0x03c2;\n  t.sigmafinal = 0x03c2;\n  t.sigmalunatesymbolgreek = 0x03f2;\n  t.sihiragana = 0x3057;\n  t.sikatakana = 0x30b7;\n  t.sikatakanahalfwidth = 0xff7c;\n  t.siluqhebrew = 0x05bd;\n  t.siluqlefthebrew = 0x05bd;\n  t.similar = 0x223c;\n  t.sindothebrew = 0x05c2;\n  t.siosacirclekorean = 0x3274;\n  t.siosaparenkorean = 0x3214;\n  t.sioscieuckorean = 0x317e;\n  t.sioscirclekorean = 0x3266;\n  t.sioskiyeokkorean = 0x317a;\n  t.sioskorean = 0x3145;\n  t.siosnieunkorean = 0x317b;\n  t.siosparenkorean = 0x3206;\n  t.siospieupkorean = 0x317d;\n  t.siostikeutkorean = 0x317c;\n  t.six = 0x0036;\n  t.sixarabic = 0x0666;\n  t.sixbengali = 0x09ec;\n  t.sixcircle = 0x2465;\n  t.sixcircleinversesansserif = 0x278f;\n  t.sixdeva = 0x096c;\n  t.sixgujarati = 0x0aec;\n  t.sixgurmukhi = 0x0a6c;\n  t.sixhackarabic = 0x0666;\n  t.sixhangzhou = 0x3026;\n  t.sixideographicparen = 0x3225;\n  t.sixinferior = 0x2086;\n  t.sixmonospace = 0xff16;\n  t.sixoldstyle = 0xf736;\n  t.sixparen = 0x2479;\n  t.sixperiod = 0x248d;\n  t.sixpersian = 0x06f6;\n  t.sixroman = 0x2175;\n  t.sixsuperior = 0x2076;\n  t.sixteencircle = 0x246f;\n  t.sixteencurrencydenominatorbengali = 0x09f9;\n  t.sixteenparen = 0x2483;\n  t.sixteenperiod = 0x2497;\n  t.sixthai = 0x0e56;\n  t.slash = 0x002f;\n  t.slashmonospace = 0xff0f;\n  t.slong = 0x017f;\n  t.slongdotaccent = 0x1e9b;\n  t.smileface = 0x263a;\n  t.smonospace = 0xff53;\n  t.sofpasuqhebrew = 0x05c3;\n  t.softhyphen = 0x00ad;\n  t.softsigncyrillic = 0x044c;\n  t.sohiragana = 0x305d;\n  t.sokatakana = 0x30bd;\n  t.sokatakanahalfwidth = 0xff7f;\n  t.soliduslongoverlaycmb = 0x0338;\n  t.solidusshortoverlaycmb = 0x0337;\n  t.sorusithai = 0x0e29;\n  t.sosalathai = 0x0e28;\n  t.sosothai = 0x0e0b;\n  t.sosuathai = 0x0e2a;\n  t.space = 0x0020;\n  t.spacehackarabic = 0x0020;\n  t.spade = 0x2660;\n  t.spadesuitblack = 0x2660;\n  t.spadesuitwhite = 0x2664;\n  t.sparen = 0x24ae;\n  t.squarebelowcmb = 0x033b;\n  t.squarecc = 0x33c4;\n  t.squarecm = 0x339d;\n  t.squarediagonalcrosshatchfill = 0x25a9;\n  t.squarehorizontalfill = 0x25a4;\n  t.squarekg = 0x338f;\n  t.squarekm = 0x339e;\n  t.squarekmcapital = 0x33ce;\n  t.squareln = 0x33d1;\n  t.squarelog = 0x33d2;\n  t.squaremg = 0x338e;\n  t.squaremil = 0x33d5;\n  t.squaremm = 0x339c;\n  t.squaremsquared = 0x33a1;\n  t.squareorthogonalcrosshatchfill = 0x25a6;\n  t.squareupperlefttolowerrightfill = 0x25a7;\n  t.squareupperrighttolowerleftfill = 0x25a8;\n  t.squareverticalfill = 0x25a5;\n  t.squarewhitewithsmallblack = 0x25a3;\n  t.srsquare = 0x33db;\n  t.ssabengali = 0x09b7;\n  t.ssadeva = 0x0937;\n  t.ssagujarati = 0x0ab7;\n  t.ssangcieuckorean = 0x3149;\n  t.ssanghieuhkorean = 0x3185;\n  t.ssangieungkorean = 0x3180;\n  t.ssangkiyeokkorean = 0x3132;\n  t.ssangnieunkorean = 0x3165;\n  t.ssangpieupkorean = 0x3143;\n  t.ssangsioskorean = 0x3146;\n  t.ssangtikeutkorean = 0x3138;\n  t.ssuperior = 0xf6f2;\n  t.sterling = 0x00a3;\n  t.sterlingmonospace = 0xffe1;\n  t.strokelongoverlaycmb = 0x0336;\n  t.strokeshortoverlaycmb = 0x0335;\n  t.subset = 0x2282;\n  t.subsetnotequal = 0x228a;\n  t.subsetorequal = 0x2286;\n  t.succeeds = 0x227b;\n  t.suchthat = 0x220b;\n  t.suhiragana = 0x3059;\n  t.sukatakana = 0x30b9;\n  t.sukatakanahalfwidth = 0xff7d;\n  t.sukunarabic = 0x0652;\n  t.summation = 0x2211;\n  t.sun = 0x263c;\n  t.superset = 0x2283;\n  t.supersetnotequal = 0x228b;\n  t.supersetorequal = 0x2287;\n  t.svsquare = 0x33dc;\n  t.syouwaerasquare = 0x337c;\n  t.t = 0x0074;\n  t.tabengali = 0x09a4;\n  t.tackdown = 0x22a4;\n  t.tackleft = 0x22a3;\n  t.tadeva = 0x0924;\n  t.tagujarati = 0x0aa4;\n  t.tagurmukhi = 0x0a24;\n  t.taharabic = 0x0637;\n  t.tahfinalarabic = 0xfec2;\n  t.tahinitialarabic = 0xfec3;\n  t.tahiragana = 0x305f;\n  t.tahmedialarabic = 0xfec4;\n  t.taisyouerasquare = 0x337d;\n  t.takatakana = 0x30bf;\n  t.takatakanahalfwidth = 0xff80;\n  t.tatweelarabic = 0x0640;\n  t.tau = 0x03c4;\n  t.tav = 0x05ea;\n  t.tavdages = 0xfb4a;\n  t.tavdagesh = 0xfb4a;\n  t.tavdageshhebrew = 0xfb4a;\n  t.tavhebrew = 0x05ea;\n  t.tbar = 0x0167;\n  t.tbopomofo = 0x310a;\n  t.tcaron = 0x0165;\n  t.tccurl = 0x02a8;\n  t.tcedilla = 0x0163;\n  t.tcheharabic = 0x0686;\n  t.tchehfinalarabic = 0xfb7b;\n  t.tchehinitialarabic = 0xfb7c;\n  t.tchehmedialarabic = 0xfb7d;\n  t.tcircle = 0x24e3;\n  t.tcircumflexbelow = 0x1e71;\n  t.tcommaaccent = 0x0163;\n  t.tdieresis = 0x1e97;\n  t.tdotaccent = 0x1e6b;\n  t.tdotbelow = 0x1e6d;\n  t.tecyrillic = 0x0442;\n  t.tedescendercyrillic = 0x04ad;\n  t.teharabic = 0x062a;\n  t.tehfinalarabic = 0xfe96;\n  t.tehhahinitialarabic = 0xfca2;\n  t.tehhahisolatedarabic = 0xfc0c;\n  t.tehinitialarabic = 0xfe97;\n  t.tehiragana = 0x3066;\n  t.tehjeeminitialarabic = 0xfca1;\n  t.tehjeemisolatedarabic = 0xfc0b;\n  t.tehmarbutaarabic = 0x0629;\n  t.tehmarbutafinalarabic = 0xfe94;\n  t.tehmedialarabic = 0xfe98;\n  t.tehmeeminitialarabic = 0xfca4;\n  t.tehmeemisolatedarabic = 0xfc0e;\n  t.tehnoonfinalarabic = 0xfc73;\n  t.tekatakana = 0x30c6;\n  t.tekatakanahalfwidth = 0xff83;\n  t.telephone = 0x2121;\n  t.telephoneblack = 0x260e;\n  t.telishagedolahebrew = 0x05a0;\n  t.telishaqetanahebrew = 0x05a9;\n  t.tencircle = 0x2469;\n  t.tenideographicparen = 0x3229;\n  t.tenparen = 0x247d;\n  t.tenperiod = 0x2491;\n  t.tenroman = 0x2179;\n  t.tesh = 0x02a7;\n  t.tet = 0x05d8;\n  t.tetdagesh = 0xfb38;\n  t.tetdageshhebrew = 0xfb38;\n  t.tethebrew = 0x05d8;\n  t.tetsecyrillic = 0x04b5;\n  t.tevirhebrew = 0x059b;\n  t.tevirlefthebrew = 0x059b;\n  t.thabengali = 0x09a5;\n  t.thadeva = 0x0925;\n  t.thagujarati = 0x0aa5;\n  t.thagurmukhi = 0x0a25;\n  t.thalarabic = 0x0630;\n  t.thalfinalarabic = 0xfeac;\n  t.thanthakhatlowleftthai = 0xf898;\n  t.thanthakhatlowrightthai = 0xf897;\n  t.thanthakhatthai = 0x0e4c;\n  t.thanthakhatupperleftthai = 0xf896;\n  t.theharabic = 0x062b;\n  t.thehfinalarabic = 0xfe9a;\n  t.thehinitialarabic = 0xfe9b;\n  t.thehmedialarabic = 0xfe9c;\n  t.thereexists = 0x2203;\n  t.therefore = 0x2234;\n  t.theta = 0x03b8;\n  t.theta1 = 0x03d1;\n  t.thetasymbolgreek = 0x03d1;\n  t.thieuthacirclekorean = 0x3279;\n  t.thieuthaparenkorean = 0x3219;\n  t.thieuthcirclekorean = 0x326b;\n  t.thieuthkorean = 0x314c;\n  t.thieuthparenkorean = 0x320b;\n  t.thirteencircle = 0x246c;\n  t.thirteenparen = 0x2480;\n  t.thirteenperiod = 0x2494;\n  t.thonangmonthothai = 0x0e11;\n  t.thook = 0x01ad;\n  t.thophuthaothai = 0x0e12;\n  t.thorn = 0x00fe;\n  t.thothahanthai = 0x0e17;\n  t.thothanthai = 0x0e10;\n  t.thothongthai = 0x0e18;\n  t.thothungthai = 0x0e16;\n  t.thousandcyrillic = 0x0482;\n  t.thousandsseparatorarabic = 0x066c;\n  t.thousandsseparatorpersian = 0x066c;\n  t.three = 0x0033;\n  t.threearabic = 0x0663;\n  t.threebengali = 0x09e9;\n  t.threecircle = 0x2462;\n  t.threecircleinversesansserif = 0x278c;\n  t.threedeva = 0x0969;\n  t.threeeighths = 0x215c;\n  t.threegujarati = 0x0ae9;\n  t.threegurmukhi = 0x0a69;\n  t.threehackarabic = 0x0663;\n  t.threehangzhou = 0x3023;\n  t.threeideographicparen = 0x3222;\n  t.threeinferior = 0x2083;\n  t.threemonospace = 0xff13;\n  t.threenumeratorbengali = 0x09f6;\n  t.threeoldstyle = 0xf733;\n  t.threeparen = 0x2476;\n  t.threeperiod = 0x248a;\n  t.threepersian = 0x06f3;\n  t.threequarters = 0x00be;\n  t.threequartersemdash = 0xf6de;\n  t.threeroman = 0x2172;\n  t.threesuperior = 0x00b3;\n  t.threethai = 0x0e53;\n  t.thzsquare = 0x3394;\n  t.tihiragana = 0x3061;\n  t.tikatakana = 0x30c1;\n  t.tikatakanahalfwidth = 0xff81;\n  t.tikeutacirclekorean = 0x3270;\n  t.tikeutaparenkorean = 0x3210;\n  t.tikeutcirclekorean = 0x3262;\n  t.tikeutkorean = 0x3137;\n  t.tikeutparenkorean = 0x3202;\n  t.tilde = 0x02dc;\n  t.tildebelowcmb = 0x0330;\n  t.tildecmb = 0x0303;\n  t.tildecomb = 0x0303;\n  t.tildedoublecmb = 0x0360;\n  t.tildeoperator = 0x223c;\n  t.tildeoverlaycmb = 0x0334;\n  t.tildeverticalcmb = 0x033e;\n  t.timescircle = 0x2297;\n  t.tipehahebrew = 0x0596;\n  t.tipehalefthebrew = 0x0596;\n  t.tippigurmukhi = 0x0a70;\n  t.titlocyrilliccmb = 0x0483;\n  t.tiwnarmenian = 0x057f;\n  t.tlinebelow = 0x1e6f;\n  t.tmonospace = 0xff54;\n  t.toarmenian = 0x0569;\n  t.tohiragana = 0x3068;\n  t.tokatakana = 0x30c8;\n  t.tokatakanahalfwidth = 0xff84;\n  t.tonebarextrahighmod = 0x02e5;\n  t.tonebarextralowmod = 0x02e9;\n  t.tonebarhighmod = 0x02e6;\n  t.tonebarlowmod = 0x02e8;\n  t.tonebarmidmod = 0x02e7;\n  t.tonefive = 0x01bd;\n  t.tonesix = 0x0185;\n  t.tonetwo = 0x01a8;\n  t.tonos = 0x0384;\n  t.tonsquare = 0x3327;\n  t.topatakthai = 0x0e0f;\n  t.tortoiseshellbracketleft = 0x3014;\n  t.tortoiseshellbracketleftsmall = 0xfe5d;\n  t.tortoiseshellbracketleftvertical = 0xfe39;\n  t.tortoiseshellbracketright = 0x3015;\n  t.tortoiseshellbracketrightsmall = 0xfe5e;\n  t.tortoiseshellbracketrightvertical = 0xfe3a;\n  t.totaothai = 0x0e15;\n  t.tpalatalhook = 0x01ab;\n  t.tparen = 0x24af;\n  t.trademark = 0x2122;\n  t.trademarksans = 0xf8ea;\n  t.trademarkserif = 0xf6db;\n  t.tretroflexhook = 0x0288;\n  t.triagdn = 0x25bc;\n  t.triaglf = 0x25c4;\n  t.triagrt = 0x25ba;\n  t.triagup = 0x25b2;\n  t.ts = 0x02a6;\n  t.tsadi = 0x05e6;\n  t.tsadidagesh = 0xfb46;\n  t.tsadidageshhebrew = 0xfb46;\n  t.tsadihebrew = 0x05e6;\n  t.tsecyrillic = 0x0446;\n  t.tsere = 0x05b5;\n  t.tsere12 = 0x05b5;\n  t.tsere1e = 0x05b5;\n  t.tsere2b = 0x05b5;\n  t.tserehebrew = 0x05b5;\n  t.tserenarrowhebrew = 0x05b5;\n  t.tserequarterhebrew = 0x05b5;\n  t.tserewidehebrew = 0x05b5;\n  t.tshecyrillic = 0x045b;\n  t.tsuperior = 0xf6f3;\n  t.ttabengali = 0x099f;\n  t.ttadeva = 0x091f;\n  t.ttagujarati = 0x0a9f;\n  t.ttagurmukhi = 0x0a1f;\n  t.tteharabic = 0x0679;\n  t.ttehfinalarabic = 0xfb67;\n  t.ttehinitialarabic = 0xfb68;\n  t.ttehmedialarabic = 0xfb69;\n  t.tthabengali = 0x09a0;\n  t.tthadeva = 0x0920;\n  t.tthagujarati = 0x0aa0;\n  t.tthagurmukhi = 0x0a20;\n  t.tturned = 0x0287;\n  t.tuhiragana = 0x3064;\n  t.tukatakana = 0x30c4;\n  t.tukatakanahalfwidth = 0xff82;\n  t.tusmallhiragana = 0x3063;\n  t.tusmallkatakana = 0x30c3;\n  t.tusmallkatakanahalfwidth = 0xff6f;\n  t.twelvecircle = 0x246b;\n  t.twelveparen = 0x247f;\n  t.twelveperiod = 0x2493;\n  t.twelveroman = 0x217b;\n  t.twentycircle = 0x2473;\n  t.twentyhangzhou = 0x5344;\n  t.twentyparen = 0x2487;\n  t.twentyperiod = 0x249b;\n  t.two = 0x0032;\n  t.twoarabic = 0x0662;\n  t.twobengali = 0x09e8;\n  t.twocircle = 0x2461;\n  t.twocircleinversesansserif = 0x278b;\n  t.twodeva = 0x0968;\n  t.twodotenleader = 0x2025;\n  t.twodotleader = 0x2025;\n  t.twodotleadervertical = 0xfe30;\n  t.twogujarati = 0x0ae8;\n  t.twogurmukhi = 0x0a68;\n  t.twohackarabic = 0x0662;\n  t.twohangzhou = 0x3022;\n  t.twoideographicparen = 0x3221;\n  t.twoinferior = 0x2082;\n  t.twomonospace = 0xff12;\n  t.twonumeratorbengali = 0x09f5;\n  t.twooldstyle = 0xf732;\n  t.twoparen = 0x2475;\n  t.twoperiod = 0x2489;\n  t.twopersian = 0x06f2;\n  t.tworoman = 0x2171;\n  t.twostroke = 0x01bb;\n  t.twosuperior = 0x00b2;\n  t.twothai = 0x0e52;\n  t.twothirds = 0x2154;\n  t.u = 0x0075;\n  t.uacute = 0x00fa;\n  t.ubar = 0x0289;\n  t.ubengali = 0x0989;\n  t.ubopomofo = 0x3128;\n  t.ubreve = 0x016d;\n  t.ucaron = 0x01d4;\n  t.ucircle = 0x24e4;\n  t.ucircumflex = 0x00fb;\n  t.ucircumflexbelow = 0x1e77;\n  t.ucyrillic = 0x0443;\n  t.udattadeva = 0x0951;\n  t.udblacute = 0x0171;\n  t.udblgrave = 0x0215;\n  t.udeva = 0x0909;\n  t.udieresis = 0x00fc;\n  t.udieresisacute = 0x01d8;\n  t.udieresisbelow = 0x1e73;\n  t.udieresiscaron = 0x01da;\n  t.udieresiscyrillic = 0x04f1;\n  t.udieresisgrave = 0x01dc;\n  t.udieresismacron = 0x01d6;\n  t.udotbelow = 0x1ee5;\n  t.ugrave = 0x00f9;\n  t.ugujarati = 0x0a89;\n  t.ugurmukhi = 0x0a09;\n  t.uhiragana = 0x3046;\n  t.uhookabove = 0x1ee7;\n  t.uhorn = 0x01b0;\n  t.uhornacute = 0x1ee9;\n  t.uhorndotbelow = 0x1ef1;\n  t.uhorngrave = 0x1eeb;\n  t.uhornhookabove = 0x1eed;\n  t.uhorntilde = 0x1eef;\n  t.uhungarumlaut = 0x0171;\n  t.uhungarumlautcyrillic = 0x04f3;\n  t.uinvertedbreve = 0x0217;\n  t.ukatakana = 0x30a6;\n  t.ukatakanahalfwidth = 0xff73;\n  t.ukcyrillic = 0x0479;\n  t.ukorean = 0x315c;\n  t.umacron = 0x016b;\n  t.umacroncyrillic = 0x04ef;\n  t.umacrondieresis = 0x1e7b;\n  t.umatragurmukhi = 0x0a41;\n  t.umonospace = 0xff55;\n  t.underscore = 0x005f;\n  t.underscoredbl = 0x2017;\n  t.underscoremonospace = 0xff3f;\n  t.underscorevertical = 0xfe33;\n  t.underscorewavy = 0xfe4f;\n  t.union = 0x222a;\n  t.universal = 0x2200;\n  t.uogonek = 0x0173;\n  t.uparen = 0x24b0;\n  t.upblock = 0x2580;\n  t.upperdothebrew = 0x05c4;\n  t.upsilon = 0x03c5;\n  t.upsilondieresis = 0x03cb;\n  t.upsilondieresistonos = 0x03b0;\n  t.upsilonlatin = 0x028a;\n  t.upsilontonos = 0x03cd;\n  t.uptackbelowcmb = 0x031d;\n  t.uptackmod = 0x02d4;\n  t.uragurmukhi = 0x0a73;\n  t.uring = 0x016f;\n  t.ushortcyrillic = 0x045e;\n  t.usmallhiragana = 0x3045;\n  t.usmallkatakana = 0x30a5;\n  t.usmallkatakanahalfwidth = 0xff69;\n  t.ustraightcyrillic = 0x04af;\n  t.ustraightstrokecyrillic = 0x04b1;\n  t.utilde = 0x0169;\n  t.utildeacute = 0x1e79;\n  t.utildebelow = 0x1e75;\n  t.uubengali = 0x098a;\n  t.uudeva = 0x090a;\n  t.uugujarati = 0x0a8a;\n  t.uugurmukhi = 0x0a0a;\n  t.uumatragurmukhi = 0x0a42;\n  t.uuvowelsignbengali = 0x09c2;\n  t.uuvowelsigndeva = 0x0942;\n  t.uuvowelsigngujarati = 0x0ac2;\n  t.uvowelsignbengali = 0x09c1;\n  t.uvowelsigndeva = 0x0941;\n  t.uvowelsigngujarati = 0x0ac1;\n  t.v = 0x0076;\n  t.vadeva = 0x0935;\n  t.vagujarati = 0x0ab5;\n  t.vagurmukhi = 0x0a35;\n  t.vakatakana = 0x30f7;\n  t.vav = 0x05d5;\n  t.vavdagesh = 0xfb35;\n  t.vavdagesh65 = 0xfb35;\n  t.vavdageshhebrew = 0xfb35;\n  t.vavhebrew = 0x05d5;\n  t.vavholam = 0xfb4b;\n  t.vavholamhebrew = 0xfb4b;\n  t.vavvavhebrew = 0x05f0;\n  t.vavyodhebrew = 0x05f1;\n  t.vcircle = 0x24e5;\n  t.vdotbelow = 0x1e7f;\n  t.vecyrillic = 0x0432;\n  t.veharabic = 0x06a4;\n  t.vehfinalarabic = 0xfb6b;\n  t.vehinitialarabic = 0xfb6c;\n  t.vehmedialarabic = 0xfb6d;\n  t.vekatakana = 0x30f9;\n  t.venus = 0x2640;\n  t.verticalbar = 0x007c;\n  t.verticallineabovecmb = 0x030d;\n  t.verticallinebelowcmb = 0x0329;\n  t.verticallinelowmod = 0x02cc;\n  t.verticallinemod = 0x02c8;\n  t.vewarmenian = 0x057e;\n  t.vhook = 0x028b;\n  t.vikatakana = 0x30f8;\n  t.viramabengali = 0x09cd;\n  t.viramadeva = 0x094d;\n  t.viramagujarati = 0x0acd;\n  t.visargabengali = 0x0983;\n  t.visargadeva = 0x0903;\n  t.visargagujarati = 0x0a83;\n  t.vmonospace = 0xff56;\n  t.voarmenian = 0x0578;\n  t.voicediterationhiragana = 0x309e;\n  t.voicediterationkatakana = 0x30fe;\n  t.voicedmarkkana = 0x309b;\n  t.voicedmarkkanahalfwidth = 0xff9e;\n  t.vokatakana = 0x30fa;\n  t.vparen = 0x24b1;\n  t.vtilde = 0x1e7d;\n  t.vturned = 0x028c;\n  t.vuhiragana = 0x3094;\n  t.vukatakana = 0x30f4;\n  t.w = 0x0077;\n  t.wacute = 0x1e83;\n  t.waekorean = 0x3159;\n  t.wahiragana = 0x308f;\n  t.wakatakana = 0x30ef;\n  t.wakatakanahalfwidth = 0xff9c;\n  t.wakorean = 0x3158;\n  t.wasmallhiragana = 0x308e;\n  t.wasmallkatakana = 0x30ee;\n  t.wattosquare = 0x3357;\n  t.wavedash = 0x301c;\n  t.wavyunderscorevertical = 0xfe34;\n  t.wawarabic = 0x0648;\n  t.wawfinalarabic = 0xfeee;\n  t.wawhamzaabovearabic = 0x0624;\n  t.wawhamzaabovefinalarabic = 0xfe86;\n  t.wbsquare = 0x33dd;\n  t.wcircle = 0x24e6;\n  t.wcircumflex = 0x0175;\n  t.wdieresis = 0x1e85;\n  t.wdotaccent = 0x1e87;\n  t.wdotbelow = 0x1e89;\n  t.wehiragana = 0x3091;\n  t.weierstrass = 0x2118;\n  t.wekatakana = 0x30f1;\n  t.wekorean = 0x315e;\n  t.weokorean = 0x315d;\n  t.wgrave = 0x1e81;\n  t.whitebullet = 0x25e6;\n  t.whitecircle = 0x25cb;\n  t.whitecircleinverse = 0x25d9;\n  t.whitecornerbracketleft = 0x300e;\n  t.whitecornerbracketleftvertical = 0xfe43;\n  t.whitecornerbracketright = 0x300f;\n  t.whitecornerbracketrightvertical = 0xfe44;\n  t.whitediamond = 0x25c7;\n  t.whitediamondcontainingblacksmalldiamond = 0x25c8;\n  t.whitedownpointingsmalltriangle = 0x25bf;\n  t.whitedownpointingtriangle = 0x25bd;\n  t.whiteleftpointingsmalltriangle = 0x25c3;\n  t.whiteleftpointingtriangle = 0x25c1;\n  t.whitelenticularbracketleft = 0x3016;\n  t.whitelenticularbracketright = 0x3017;\n  t.whiterightpointingsmalltriangle = 0x25b9;\n  t.whiterightpointingtriangle = 0x25b7;\n  t.whitesmallsquare = 0x25ab;\n  t.whitesmilingface = 0x263a;\n  t.whitesquare = 0x25a1;\n  t.whitestar = 0x2606;\n  t.whitetelephone = 0x260f;\n  t.whitetortoiseshellbracketleft = 0x3018;\n  t.whitetortoiseshellbracketright = 0x3019;\n  t.whiteuppointingsmalltriangle = 0x25b5;\n  t.whiteuppointingtriangle = 0x25b3;\n  t.wihiragana = 0x3090;\n  t.wikatakana = 0x30f0;\n  t.wikorean = 0x315f;\n  t.wmonospace = 0xff57;\n  t.wohiragana = 0x3092;\n  t.wokatakana = 0x30f2;\n  t.wokatakanahalfwidth = 0xff66;\n  t.won = 0x20a9;\n  t.wonmonospace = 0xffe6;\n  t.wowaenthai = 0x0e27;\n  t.wparen = 0x24b2;\n  t.wring = 0x1e98;\n  t.wsuperior = 0x02b7;\n  t.wturned = 0x028d;\n  t.wynn = 0x01bf;\n  t.x = 0x0078;\n  t.xabovecmb = 0x033d;\n  t.xbopomofo = 0x3112;\n  t.xcircle = 0x24e7;\n  t.xdieresis = 0x1e8d;\n  t.xdotaccent = 0x1e8b;\n  t.xeharmenian = 0x056d;\n  t.xi = 0x03be;\n  t.xmonospace = 0xff58;\n  t.xparen = 0x24b3;\n  t.xsuperior = 0x02e3;\n  t.y = 0x0079;\n  t.yaadosquare = 0x334e;\n  t.yabengali = 0x09af;\n  t.yacute = 0x00fd;\n  t.yadeva = 0x092f;\n  t.yaekorean = 0x3152;\n  t.yagujarati = 0x0aaf;\n  t.yagurmukhi = 0x0a2f;\n  t.yahiragana = 0x3084;\n  t.yakatakana = 0x30e4;\n  t.yakatakanahalfwidth = 0xff94;\n  t.yakorean = 0x3151;\n  t.yamakkanthai = 0x0e4e;\n  t.yasmallhiragana = 0x3083;\n  t.yasmallkatakana = 0x30e3;\n  t.yasmallkatakanahalfwidth = 0xff6c;\n  t.yatcyrillic = 0x0463;\n  t.ycircle = 0x24e8;\n  t.ycircumflex = 0x0177;\n  t.ydieresis = 0x00ff;\n  t.ydotaccent = 0x1e8f;\n  t.ydotbelow = 0x1ef5;\n  t.yeharabic = 0x064a;\n  t.yehbarreearabic = 0x06d2;\n  t.yehbarreefinalarabic = 0xfbaf;\n  t.yehfinalarabic = 0xfef2;\n  t.yehhamzaabovearabic = 0x0626;\n  t.yehhamzaabovefinalarabic = 0xfe8a;\n  t.yehhamzaaboveinitialarabic = 0xfe8b;\n  t.yehhamzaabovemedialarabic = 0xfe8c;\n  t.yehinitialarabic = 0xfef3;\n  t.yehmedialarabic = 0xfef4;\n  t.yehmeeminitialarabic = 0xfcdd;\n  t.yehmeemisolatedarabic = 0xfc58;\n  t.yehnoonfinalarabic = 0xfc94;\n  t.yehthreedotsbelowarabic = 0x06d1;\n  t.yekorean = 0x3156;\n  t.yen = 0x00a5;\n  t.yenmonospace = 0xffe5;\n  t.yeokorean = 0x3155;\n  t.yeorinhieuhkorean = 0x3186;\n  t.yerahbenyomohebrew = 0x05aa;\n  t.yerahbenyomolefthebrew = 0x05aa;\n  t.yericyrillic = 0x044b;\n  t.yerudieresiscyrillic = 0x04f9;\n  t.yesieungkorean = 0x3181;\n  t.yesieungpansioskorean = 0x3183;\n  t.yesieungsioskorean = 0x3182;\n  t.yetivhebrew = 0x059a;\n  t.ygrave = 0x1ef3;\n  t.yhook = 0x01b4;\n  t.yhookabove = 0x1ef7;\n  t.yiarmenian = 0x0575;\n  t.yicyrillic = 0x0457;\n  t.yikorean = 0x3162;\n  t.yinyang = 0x262f;\n  t.yiwnarmenian = 0x0582;\n  t.ymonospace = 0xff59;\n  t.yod = 0x05d9;\n  t.yoddagesh = 0xfb39;\n  t.yoddageshhebrew = 0xfb39;\n  t.yodhebrew = 0x05d9;\n  t.yodyodhebrew = 0x05f2;\n  t.yodyodpatahhebrew = 0xfb1f;\n  t.yohiragana = 0x3088;\n  t.yoikorean = 0x3189;\n  t.yokatakana = 0x30e8;\n  t.yokatakanahalfwidth = 0xff96;\n  t.yokorean = 0x315b;\n  t.yosmallhiragana = 0x3087;\n  t.yosmallkatakana = 0x30e7;\n  t.yosmallkatakanahalfwidth = 0xff6e;\n  t.yotgreek = 0x03f3;\n  t.yoyaekorean = 0x3188;\n  t.yoyakorean = 0x3187;\n  t.yoyakthai = 0x0e22;\n  t.yoyingthai = 0x0e0d;\n  t.yparen = 0x24b4;\n  t.ypogegrammeni = 0x037a;\n  t.ypogegrammenigreekcmb = 0x0345;\n  t.yr = 0x01a6;\n  t.yring = 0x1e99;\n  t.ysuperior = 0x02b8;\n  t.ytilde = 0x1ef9;\n  t.yturned = 0x028e;\n  t.yuhiragana = 0x3086;\n  t.yuikorean = 0x318c;\n  t.yukatakana = 0x30e6;\n  t.yukatakanahalfwidth = 0xff95;\n  t.yukorean = 0x3160;\n  t.yusbigcyrillic = 0x046b;\n  t.yusbigiotifiedcyrillic = 0x046d;\n  t.yuslittlecyrillic = 0x0467;\n  t.yuslittleiotifiedcyrillic = 0x0469;\n  t.yusmallhiragana = 0x3085;\n  t.yusmallkatakana = 0x30e5;\n  t.yusmallkatakanahalfwidth = 0xff6d;\n  t.yuyekorean = 0x318b;\n  t.yuyeokorean = 0x318a;\n  t.yyabengali = 0x09df;\n  t.yyadeva = 0x095f;\n  t.z = 0x007a;\n  t.zaarmenian = 0x0566;\n  t.zacute = 0x017a;\n  t.zadeva = 0x095b;\n  t.zagurmukhi = 0x0a5b;\n  t.zaharabic = 0x0638;\n  t.zahfinalarabic = 0xfec6;\n  t.zahinitialarabic = 0xfec7;\n  t.zahiragana = 0x3056;\n  t.zahmedialarabic = 0xfec8;\n  t.zainarabic = 0x0632;\n  t.zainfinalarabic = 0xfeb0;\n  t.zakatakana = 0x30b6;\n  t.zaqefgadolhebrew = 0x0595;\n  t.zaqefqatanhebrew = 0x0594;\n  t.zarqahebrew = 0x0598;\n  t.zayin = 0x05d6;\n  t.zayindagesh = 0xfb36;\n  t.zayindageshhebrew = 0xfb36;\n  t.zayinhebrew = 0x05d6;\n  t.zbopomofo = 0x3117;\n  t.zcaron = 0x017e;\n  t.zcircle = 0x24e9;\n  t.zcircumflex = 0x1e91;\n  t.zcurl = 0x0291;\n  t.zdot = 0x017c;\n  t.zdotaccent = 0x017c;\n  t.zdotbelow = 0x1e93;\n  t.zecyrillic = 0x0437;\n  t.zedescendercyrillic = 0x0499;\n  t.zedieresiscyrillic = 0x04df;\n  t.zehiragana = 0x305c;\n  t.zekatakana = 0x30bc;\n  t.zero = 0x0030;\n  t.zeroarabic = 0x0660;\n  t.zerobengali = 0x09e6;\n  t.zerodeva = 0x0966;\n  t.zerogujarati = 0x0ae6;\n  t.zerogurmukhi = 0x0a66;\n  t.zerohackarabic = 0x0660;\n  t.zeroinferior = 0x2080;\n  t.zeromonospace = 0xff10;\n  t.zerooldstyle = 0xf730;\n  t.zeropersian = 0x06f0;\n  t.zerosuperior = 0x2070;\n  t.zerothai = 0x0e50;\n  t.zerowidthjoiner = 0xfeff;\n  t.zerowidthnonjoiner = 0x200c;\n  t.zerowidthspace = 0x200b;\n  t.zeta = 0x03b6;\n  t.zhbopomofo = 0x3113;\n  t.zhearmenian = 0x056a;\n  t.zhebrevecyrillic = 0x04c2;\n  t.zhecyrillic = 0x0436;\n  t.zhedescendercyrillic = 0x0497;\n  t.zhedieresiscyrillic = 0x04dd;\n  t.zihiragana = 0x3058;\n  t.zikatakana = 0x30b8;\n  t.zinorhebrew = 0x05ae;\n  t.zlinebelow = 0x1e95;\n  t.zmonospace = 0xff5a;\n  t.zohiragana = 0x305e;\n  t.zokatakana = 0x30be;\n  t.zparen = 0x24b5;\n  t.zretroflexhook = 0x0290;\n  t.zstroke = 0x01b6;\n  t.zuhiragana = 0x305a;\n  t.zukatakana = 0x30ba;\n  t[\".notdef\"] = 0x0000;\n  t.angbracketleftbig = 0x2329;\n  t.angbracketleftBig = 0x2329;\n  t.angbracketleftbigg = 0x2329;\n  t.angbracketleftBigg = 0x2329;\n  t.angbracketrightBig = 0x232a;\n  t.angbracketrightbig = 0x232a;\n  t.angbracketrightBigg = 0x232a;\n  t.angbracketrightbigg = 0x232a;\n  t.arrowhookleft = 0x21aa;\n  t.arrowhookright = 0x21a9;\n  t.arrowlefttophalf = 0x21bc;\n  t.arrowleftbothalf = 0x21bd;\n  t.arrownortheast = 0x2197;\n  t.arrownorthwest = 0x2196;\n  t.arrowrighttophalf = 0x21c0;\n  t.arrowrightbothalf = 0x21c1;\n  t.arrowsoutheast = 0x2198;\n  t.arrowsouthwest = 0x2199;\n  t.backslashbig = 0x2216;\n  t.backslashBig = 0x2216;\n  t.backslashBigg = 0x2216;\n  t.backslashbigg = 0x2216;\n  t.bardbl = 0x2016;\n  t.bracehtipdownleft = 0xfe37;\n  t.bracehtipdownright = 0xfe37;\n  t.bracehtipupleft = 0xfe38;\n  t.bracehtipupright = 0xfe38;\n  t.braceleftBig = 0x007b;\n  t.braceleftbig = 0x007b;\n  t.braceleftbigg = 0x007b;\n  t.braceleftBigg = 0x007b;\n  t.bracerightBig = 0x007d;\n  t.bracerightbig = 0x007d;\n  t.bracerightbigg = 0x007d;\n  t.bracerightBigg = 0x007d;\n  t.bracketleftbig = 0x005b;\n  t.bracketleftBig = 0x005b;\n  t.bracketleftbigg = 0x005b;\n  t.bracketleftBigg = 0x005b;\n  t.bracketrightBig = 0x005d;\n  t.bracketrightbig = 0x005d;\n  t.bracketrightbigg = 0x005d;\n  t.bracketrightBigg = 0x005d;\n  t.ceilingleftbig = 0x2308;\n  t.ceilingleftBig = 0x2308;\n  t.ceilingleftBigg = 0x2308;\n  t.ceilingleftbigg = 0x2308;\n  t.ceilingrightbig = 0x2309;\n  t.ceilingrightBig = 0x2309;\n  t.ceilingrightbigg = 0x2309;\n  t.ceilingrightBigg = 0x2309;\n  t.circledotdisplay = 0x2299;\n  t.circledottext = 0x2299;\n  t.circlemultiplydisplay = 0x2297;\n  t.circlemultiplytext = 0x2297;\n  t.circleplusdisplay = 0x2295;\n  t.circleplustext = 0x2295;\n  t.contintegraldisplay = 0x222e;\n  t.contintegraltext = 0x222e;\n  t.coproductdisplay = 0x2210;\n  t.coproducttext = 0x2210;\n  t.floorleftBig = 0x230a;\n  t.floorleftbig = 0x230a;\n  t.floorleftbigg = 0x230a;\n  t.floorleftBigg = 0x230a;\n  t.floorrightbig = 0x230b;\n  t.floorrightBig = 0x230b;\n  t.floorrightBigg = 0x230b;\n  t.floorrightbigg = 0x230b;\n  t.hatwide = 0x0302;\n  t.hatwider = 0x0302;\n  t.hatwidest = 0x0302;\n  t.intercal = 0x1d40;\n  t.integraldisplay = 0x222b;\n  t.integraltext = 0x222b;\n  t.intersectiondisplay = 0x22c2;\n  t.intersectiontext = 0x22c2;\n  t.logicalanddisplay = 0x2227;\n  t.logicalandtext = 0x2227;\n  t.logicalordisplay = 0x2228;\n  t.logicalortext = 0x2228;\n  t.parenleftBig = 0x0028;\n  t.parenleftbig = 0x0028;\n  t.parenleftBigg = 0x0028;\n  t.parenleftbigg = 0x0028;\n  t.parenrightBig = 0x0029;\n  t.parenrightbig = 0x0029;\n  t.parenrightBigg = 0x0029;\n  t.parenrightbigg = 0x0029;\n  t.prime = 0x2032;\n  t.productdisplay = 0x220f;\n  t.producttext = 0x220f;\n  t.radicalbig = 0x221a;\n  t.radicalBig = 0x221a;\n  t.radicalBigg = 0x221a;\n  t.radicalbigg = 0x221a;\n  t.radicalbt = 0x221a;\n  t.radicaltp = 0x221a;\n  t.radicalvertex = 0x221a;\n  t.slashbig = 0x002f;\n  t.slashBig = 0x002f;\n  t.slashBigg = 0x002f;\n  t.slashbigg = 0x002f;\n  t.summationdisplay = 0x2211;\n  t.summationtext = 0x2211;\n  t.tildewide = 0x02dc;\n  t.tildewider = 0x02dc;\n  t.tildewidest = 0x02dc;\n  t.uniondisplay = 0x22c3;\n  t.unionmultidisplay = 0x228e;\n  t.unionmultitext = 0x228e;\n  t.unionsqdisplay = 0x2294;\n  t.unionsqtext = 0x2294;\n  t.uniontext = 0x22c3;\n  t.vextenddouble = 0x2225;\n  t.vextendsingle = 0x2223;\n});\nconst getDingbatsGlyphsUnicode = getLookupTableFactory(function (t) {\n  t.space = 0x0020;\n  t.a1 = 0x2701;\n  t.a2 = 0x2702;\n  t.a202 = 0x2703;\n  t.a3 = 0x2704;\n  t.a4 = 0x260e;\n  t.a5 = 0x2706;\n  t.a119 = 0x2707;\n  t.a118 = 0x2708;\n  t.a117 = 0x2709;\n  t.a11 = 0x261b;\n  t.a12 = 0x261e;\n  t.a13 = 0x270c;\n  t.a14 = 0x270d;\n  t.a15 = 0x270e;\n  t.a16 = 0x270f;\n  t.a105 = 0x2710;\n  t.a17 = 0x2711;\n  t.a18 = 0x2712;\n  t.a19 = 0x2713;\n  t.a20 = 0x2714;\n  t.a21 = 0x2715;\n  t.a22 = 0x2716;\n  t.a23 = 0x2717;\n  t.a24 = 0x2718;\n  t.a25 = 0x2719;\n  t.a26 = 0x271a;\n  t.a27 = 0x271b;\n  t.a28 = 0x271c;\n  t.a6 = 0x271d;\n  t.a7 = 0x271e;\n  t.a8 = 0x271f;\n  t.a9 = 0x2720;\n  t.a10 = 0x2721;\n  t.a29 = 0x2722;\n  t.a30 = 0x2723;\n  t.a31 = 0x2724;\n  t.a32 = 0x2725;\n  t.a33 = 0x2726;\n  t.a34 = 0x2727;\n  t.a35 = 0x2605;\n  t.a36 = 0x2729;\n  t.a37 = 0x272a;\n  t.a38 = 0x272b;\n  t.a39 = 0x272c;\n  t.a40 = 0x272d;\n  t.a41 = 0x272e;\n  t.a42 = 0x272f;\n  t.a43 = 0x2730;\n  t.a44 = 0x2731;\n  t.a45 = 0x2732;\n  t.a46 = 0x2733;\n  t.a47 = 0x2734;\n  t.a48 = 0x2735;\n  t.a49 = 0x2736;\n  t.a50 = 0x2737;\n  t.a51 = 0x2738;\n  t.a52 = 0x2739;\n  t.a53 = 0x273a;\n  t.a54 = 0x273b;\n  t.a55 = 0x273c;\n  t.a56 = 0x273d;\n  t.a57 = 0x273e;\n  t.a58 = 0x273f;\n  t.a59 = 0x2740;\n  t.a60 = 0x2741;\n  t.a61 = 0x2742;\n  t.a62 = 0x2743;\n  t.a63 = 0x2744;\n  t.a64 = 0x2745;\n  t.a65 = 0x2746;\n  t.a66 = 0x2747;\n  t.a67 = 0x2748;\n  t.a68 = 0x2749;\n  t.a69 = 0x274a;\n  t.a70 = 0x274b;\n  t.a71 = 0x25cf;\n  t.a72 = 0x274d;\n  t.a73 = 0x25a0;\n  t.a74 = 0x274f;\n  t.a203 = 0x2750;\n  t.a75 = 0x2751;\n  t.a204 = 0x2752;\n  t.a76 = 0x25b2;\n  t.a77 = 0x25bc;\n  t.a78 = 0x25c6;\n  t.a79 = 0x2756;\n  t.a81 = 0x25d7;\n  t.a82 = 0x2758;\n  t.a83 = 0x2759;\n  t.a84 = 0x275a;\n  t.a97 = 0x275b;\n  t.a98 = 0x275c;\n  t.a99 = 0x275d;\n  t.a100 = 0x275e;\n  t.a101 = 0x2761;\n  t.a102 = 0x2762;\n  t.a103 = 0x2763;\n  t.a104 = 0x2764;\n  t.a106 = 0x2765;\n  t.a107 = 0x2766;\n  t.a108 = 0x2767;\n  t.a112 = 0x2663;\n  t.a111 = 0x2666;\n  t.a110 = 0x2665;\n  t.a109 = 0x2660;\n  t.a120 = 0x2460;\n  t.a121 = 0x2461;\n  t.a122 = 0x2462;\n  t.a123 = 0x2463;\n  t.a124 = 0x2464;\n  t.a125 = 0x2465;\n  t.a126 = 0x2466;\n  t.a127 = 0x2467;\n  t.a128 = 0x2468;\n  t.a129 = 0x2469;\n  t.a130 = 0x2776;\n  t.a131 = 0x2777;\n  t.a132 = 0x2778;\n  t.a133 = 0x2779;\n  t.a134 = 0x277a;\n  t.a135 = 0x277b;\n  t.a136 = 0x277c;\n  t.a137 = 0x277d;\n  t.a138 = 0x277e;\n  t.a139 = 0x277f;\n  t.a140 = 0x2780;\n  t.a141 = 0x2781;\n  t.a142 = 0x2782;\n  t.a143 = 0x2783;\n  t.a144 = 0x2784;\n  t.a145 = 0x2785;\n  t.a146 = 0x2786;\n  t.a147 = 0x2787;\n  t.a148 = 0x2788;\n  t.a149 = 0x2789;\n  t.a150 = 0x278a;\n  t.a151 = 0x278b;\n  t.a152 = 0x278c;\n  t.a153 = 0x278d;\n  t.a154 = 0x278e;\n  t.a155 = 0x278f;\n  t.a156 = 0x2790;\n  t.a157 = 0x2791;\n  t.a158 = 0x2792;\n  t.a159 = 0x2793;\n  t.a160 = 0x2794;\n  t.a161 = 0x2192;\n  t.a163 = 0x2194;\n  t.a164 = 0x2195;\n  t.a196 = 0x2798;\n  t.a165 = 0x2799;\n  t.a192 = 0x279a;\n  t.a166 = 0x279b;\n  t.a167 = 0x279c;\n  t.a168 = 0x279d;\n  t.a169 = 0x279e;\n  t.a170 = 0x279f;\n  t.a171 = 0x27a0;\n  t.a172 = 0x27a1;\n  t.a173 = 0x27a2;\n  t.a162 = 0x27a3;\n  t.a174 = 0x27a4;\n  t.a175 = 0x27a5;\n  t.a176 = 0x27a6;\n  t.a177 = 0x27a7;\n  t.a178 = 0x27a8;\n  t.a179 = 0x27a9;\n  t.a193 = 0x27aa;\n  t.a180 = 0x27ab;\n  t.a199 = 0x27ac;\n  t.a181 = 0x27ad;\n  t.a200 = 0x27ae;\n  t.a182 = 0x27af;\n  t.a201 = 0x27b1;\n  t.a183 = 0x27b2;\n  t.a184 = 0x27b3;\n  t.a197 = 0x27b4;\n  t.a185 = 0x27b5;\n  t.a194 = 0x27b6;\n  t.a198 = 0x27b7;\n  t.a186 = 0x27b8;\n  t.a195 = 0x27b9;\n  t.a187 = 0x27ba;\n  t.a188 = 0x27bb;\n  t.a189 = 0x27bc;\n  t.a190 = 0x27bd;\n  t.a191 = 0x27be;\n  t.a89 = 0x2768;\n  t.a90 = 0x2769;\n  t.a93 = 0x276a;\n  t.a94 = 0x276b;\n  t.a91 = 0x276c;\n  t.a92 = 0x276d;\n  t.a205 = 0x276e;\n  t.a85 = 0x276f;\n  t.a206 = 0x2770;\n  t.a86 = 0x2771;\n  t.a87 = 0x2772;\n  t.a88 = 0x2773;\n  t.a95 = 0x2774;\n  t.a96 = 0x2775;\n  t[\".notdef\"] = 0x0000;\n});\n\n;// ./src/core/unicode.js\n\nconst getSpecialPUASymbols = getLookupTableFactory(function (t) {\n  t[63721] = 0x00a9;\n  t[63193] = 0x00a9;\n  t[63720] = 0x00ae;\n  t[63194] = 0x00ae;\n  t[63722] = 0x2122;\n  t[63195] = 0x2122;\n  t[63729] = 0x23a7;\n  t[63730] = 0x23a8;\n  t[63731] = 0x23a9;\n  t[63740] = 0x23ab;\n  t[63741] = 0x23ac;\n  t[63742] = 0x23ad;\n  t[63726] = 0x23a1;\n  t[63727] = 0x23a2;\n  t[63728] = 0x23a3;\n  t[63737] = 0x23a4;\n  t[63738] = 0x23a5;\n  t[63739] = 0x23a6;\n  t[63723] = 0x239b;\n  t[63724] = 0x239c;\n  t[63725] = 0x239d;\n  t[63734] = 0x239e;\n  t[63735] = 0x239f;\n  t[63736] = 0x23a0;\n});\nfunction mapSpecialUnicodeValues(code) {\n  if (code >= 0xfff0 && code <= 0xffff) {\n    return 0;\n  } else if (code >= 0xf600 && code <= 0xf8ff) {\n    return getSpecialPUASymbols()[code] || code;\n  } else if (code === 0x00ad) {\n    return 0x002d;\n  }\n  return code;\n}\nfunction getUnicodeForGlyph(name, glyphsUnicodeMap) {\n  let unicode = glyphsUnicodeMap[name];\n  if (unicode !== undefined) {\n    return unicode;\n  }\n  if (!name) {\n    return -1;\n  }\n  if (name[0] === \"u\") {\n    const nameLen = name.length;\n    let hexStr;\n    if (nameLen === 7 && name[1] === \"n\" && name[2] === \"i\") {\n      hexStr = name.substring(3);\n    } else if (nameLen >= 5 && nameLen <= 7) {\n      hexStr = name.substring(1);\n    } else {\n      return -1;\n    }\n    if (hexStr === hexStr.toUpperCase()) {\n      unicode = parseInt(hexStr, 16);\n      if (unicode >= 0) {\n        return unicode;\n      }\n    }\n  }\n  return -1;\n}\nconst UnicodeRanges = [[0x0000, 0x007f], [0x0080, 0x00ff], [0x0100, 0x017f], [0x0180, 0x024f], [0x0250, 0x02af, 0x1d00, 0x1d7f, 0x1d80, 0x1dbf], [0x02b0, 0x02ff, 0xa700, 0xa71f], [0x0300, 0x036f, 0x1dc0, 0x1dff], [0x0370, 0x03ff], [0x2c80, 0x2cff], [0x0400, 0x04ff, 0x0500, 0x052f, 0x2de0, 0x2dff, 0xa640, 0xa69f], [0x0530, 0x058f], [0x0590, 0x05ff], [0xa500, 0xa63f], [0x0600, 0x06ff, 0x0750, 0x077f], [0x07c0, 0x07ff], [0x0900, 0x097f], [0x0980, 0x09ff], [0x0a00, 0x0a7f], [0x0a80, 0x0aff], [0x0b00, 0x0b7f], [0x0b80, 0x0bff], [0x0c00, 0x0c7f], [0x0c80, 0x0cff], [0x0d00, 0x0d7f], [0x0e00, 0x0e7f], [0x0e80, 0x0eff], [0x10a0, 0x10ff, 0x2d00, 0x2d2f], [0x1b00, 0x1b7f], [0x1100, 0x11ff], [0x1e00, 0x1eff, 0x2c60, 0x2c7f, 0xa720, 0xa7ff], [0x1f00, 0x1fff], [0x2000, 0x206f, 0x2e00, 0x2e7f], [0x2070, 0x209f], [0x20a0, 0x20cf], [0x20d0, 0x20ff], [0x2100, 0x214f], [0x2150, 0x218f], [0x2190, 0x21ff, 0x27f0, 0x27ff, 0x2900, 0x297f, 0x2b00, 0x2bff], [0x2200, 0x22ff, 0x2a00, 0x2aff, 0x27c0, 0x27ef, 0x2980, 0x29ff], [0x2300, 0x23ff], [0x2400, 0x243f], [0x2440, 0x245f], [0x2460, 0x24ff], [0x2500, 0x257f], [0x2580, 0x259f], [0x25a0, 0x25ff], [0x2600, 0x26ff], [0x2700, 0x27bf], [0x3000, 0x303f], [0x3040, 0x309f], [0x30a0, 0x30ff, 0x31f0, 0x31ff], [0x3100, 0x312f, 0x31a0, 0x31bf], [0x3130, 0x318f], [0xa840, 0xa87f], [0x3200, 0x32ff], [0x3300, 0x33ff], [0xac00, 0xd7af], [0xd800, 0xdfff], [0x10900, 0x1091f], [0x4e00, 0x9fff, 0x2e80, 0x2eff, 0x2f00, 0x2fdf, 0x2ff0, 0x2fff, 0x3400, 0x4dbf, 0x20000, 0x2a6df, 0x3190, 0x319f], [0xe000, 0xf8ff], [0x31c0, 0x31ef, 0xf900, 0xfaff, 0x2f800, 0x2fa1f], [0xfb00, 0xfb4f], [0xfb50, 0xfdff], [0xfe20, 0xfe2f], [0xfe10, 0xfe1f], [0xfe50, 0xfe6f], [0xfe70, 0xfeff], [0xff00, 0xffef], [0xfff0, 0xffff], [0x0f00, 0x0fff], [0x0700, 0x074f], [0x0780, 0x07bf], [0x0d80, 0x0dff], [0x1000, 0x109f], [0x1200, 0x137f, 0x1380, 0x139f, 0x2d80, 0x2ddf], [0x13a0, 0x13ff], [0x1400, 0x167f], [0x1680, 0x169f], [0x16a0, 0x16ff], [0x1780, 0x17ff], [0x1800, 0x18af], [0x2800, 0x28ff], [0xa000, 0xa48f], [0x1700, 0x171f, 0x1720, 0x173f, 0x1740, 0x175f, 0x1760, 0x177f], [0x10300, 0x1032f], [0x10330, 0x1034f], [0x10400, 0x1044f], [0x1d000, 0x1d0ff, 0x1d100, 0x1d1ff, 0x1d200, 0x1d24f], [0x1d400, 0x1d7ff], [0xff000, 0xffffd], [0xfe00, 0xfe0f, 0xe0100, 0xe01ef], [0xe0000, 0xe007f], [0x1900, 0x194f], [0x1950, 0x197f], [0x1980, 0x19df], [0x1a00, 0x1a1f], [0x2c00, 0x2c5f], [0x2d30, 0x2d7f], [0x4dc0, 0x4dff], [0xa800, 0xa82f], [0x10000, 0x1007f, 0x10080, 0x100ff, 0x10100, 0x1013f], [0x10140, 0x1018f], [0x10380, 0x1039f], [0x103a0, 0x103df], [0x10450, 0x1047f], [0x10480, 0x104af], [0x10800, 0x1083f], [0x10a00, 0x10a5f], [0x1d300, 0x1d35f], [0x12000, 0x123ff, 0x12400, 0x1247f], [0x1d360, 0x1d37f], [0x1b80, 0x1bbf], [0x1c00, 0x1c4f], [0x1c50, 0x1c7f], [0xa880, 0xa8df], [0xa900, 0xa92f], [0xa930, 0xa95f], [0xaa00, 0xaa5f], [0x10190, 0x101cf], [0x101d0, 0x101ff], [0x102a0, 0x102df, 0x10280, 0x1029f, 0x10920, 0x1093f], [0x1f030, 0x1f09f, 0x1f000, 0x1f02f]];\nfunction getUnicodeRangeFor(value, lastPosition = -1) {\n  if (lastPosition !== -1) {\n    const range = UnicodeRanges[lastPosition];\n    for (let i = 0, ii = range.length; i < ii; i += 2) {\n      if (value >= range[i] && value <= range[i + 1]) {\n        return lastPosition;\n      }\n    }\n  }\n  for (let i = 0, ii = UnicodeRanges.length; i < ii; i++) {\n    const range = UnicodeRanges[i];\n    for (let j = 0, jj = range.length; j < jj; j += 2) {\n      if (value >= range[j] && value <= range[j + 1]) {\n        return i;\n      }\n    }\n  }\n  return -1;\n}\nconst SpecialCharRegExp = new RegExp(\"^(\\\\s)|(\\\\p{Mn})|(\\\\p{Cf})$\", \"u\");\nconst CategoryCache = new Map();\nfunction getCharUnicodeCategory(char) {\n  const cachedCategory = CategoryCache.get(char);\n  if (cachedCategory) {\n    return cachedCategory;\n  }\n  const groups = char.match(SpecialCharRegExp);\n  const category = {\n    isWhitespace: !!groups?.[1],\n    isZeroWidthDiacritic: !!groups?.[2],\n    isInvisibleFormatMark: !!groups?.[3]\n  };\n  CategoryCache.set(char, category);\n  return category;\n}\nfunction clearUnicodeCaches() {\n  CategoryCache.clear();\n}\n\n;// ./src/core/fonts_utils.js\n\n\n\n\nconst SEAC_ANALYSIS_ENABLED = true;\nconst FontFlags = {\n  FixedPitch: 1,\n  Serif: 2,\n  Symbolic: 4,\n  Script: 8,\n  Nonsymbolic: 32,\n  Italic: 64,\n  AllCap: 65536,\n  SmallCap: 131072,\n  ForceBold: 262144\n};\nconst MacStandardGlyphOrdering = [\".notdef\", \".null\", \"nonmarkingreturn\", \"space\", \"exclam\", \"quotedbl\", \"numbersign\", \"dollar\", \"percent\", \"ampersand\", \"quotesingle\", \"parenleft\", \"parenright\", \"asterisk\", \"plus\", \"comma\", \"hyphen\", \"period\", \"slash\", \"zero\", \"one\", \"two\", \"three\", \"four\", \"five\", \"six\", \"seven\", \"eight\", \"nine\", \"colon\", \"semicolon\", \"less\", \"equal\", \"greater\", \"question\", \"at\", \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\", \"J\", \"K\", \"L\", \"M\", \"N\", \"O\", \"P\", \"Q\", \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\", \"Y\", \"Z\", \"bracketleft\", \"backslash\", \"bracketright\", \"asciicircum\", \"underscore\", \"grave\", \"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\", \"k\", \"l\", \"m\", \"n\", \"o\", \"p\", \"q\", \"r\", \"s\", \"t\", \"u\", \"v\", \"w\", \"x\", \"y\", \"z\", \"braceleft\", \"bar\", \"braceright\", \"asciitilde\", \"Adieresis\", \"Aring\", \"Ccedilla\", \"Eacute\", \"Ntilde\", \"Odieresis\", \"Udieresis\", \"aacute\", \"agrave\", \"acircumflex\", \"adieresis\", \"atilde\", \"aring\", \"ccedilla\", \"eacute\", \"egrave\", \"ecircumflex\", \"edieresis\", \"iacute\", \"igrave\", \"icircumflex\", \"idieresis\", \"ntilde\", \"oacute\", \"ograve\", \"ocircumflex\", \"odieresis\", \"otilde\", \"uacute\", \"ugrave\", \"ucircumflex\", \"udieresis\", \"dagger\", \"degree\", \"cent\", \"sterling\", \"section\", \"bullet\", \"paragraph\", \"germandbls\", \"registered\", \"copyright\", \"trademark\", \"acute\", \"dieresis\", \"notequal\", \"AE\", \"Oslash\", \"infinity\", \"plusminus\", \"lessequal\", \"greaterequal\", \"yen\", \"mu\", \"partialdiff\", \"summation\", \"product\", \"pi\", \"integral\", \"ordfeminine\", \"ordmasculine\", \"Omega\", \"ae\", \"oslash\", \"questiondown\", \"exclamdown\", \"logicalnot\", \"radical\", \"florin\", \"approxequal\", \"Delta\", \"guillemotleft\", \"guillemotright\", \"ellipsis\", \"nonbreakingspace\", \"Agrave\", \"Atilde\", \"Otilde\", \"OE\", \"oe\", \"endash\", \"emdash\", \"quotedblleft\", \"quotedblright\", \"quoteleft\", \"quoteright\", \"divide\", \"lozenge\", \"ydieresis\", \"Ydieresis\", \"fraction\", \"currency\", \"guilsinglleft\", \"guilsinglright\", \"fi\", \"fl\", \"daggerdbl\", \"periodcentered\", \"quotesinglbase\", \"quotedblbase\", \"perthousand\", \"Acircumflex\", \"Ecircumflex\", \"Aacute\", \"Edieresis\", \"Egrave\", \"Iacute\", \"Icircumflex\", \"Idieresis\", \"Igrave\", \"Oacute\", \"Ocircumflex\", \"apple\", \"Ograve\", \"Uacute\", \"Ucircumflex\", \"Ugrave\", \"dotlessi\", \"circumflex\", \"tilde\", \"macron\", \"breve\", \"dotaccent\", \"ring\", \"cedilla\", \"hungarumlaut\", \"ogonek\", \"caron\", \"Lslash\", \"lslash\", \"Scaron\", \"scaron\", \"Zcaron\", \"zcaron\", \"brokenbar\", \"Eth\", \"eth\", \"Yacute\", \"yacute\", \"Thorn\", \"thorn\", \"minus\", \"multiply\", \"onesuperior\", \"twosuperior\", \"threesuperior\", \"onehalf\", \"onequarter\", \"threequarters\", \"franc\", \"Gbreve\", \"gbreve\", \"Idotaccent\", \"Scedilla\", \"scedilla\", \"Cacute\", \"cacute\", \"Ccaron\", \"ccaron\", \"dcroat\"];\nfunction recoverGlyphName(name, glyphsUnicodeMap) {\n  if (glyphsUnicodeMap[name] !== undefined) {\n    return name;\n  }\n  const unicode = getUnicodeForGlyph(name, glyphsUnicodeMap);\n  if (unicode !== -1) {\n    for (const key in glyphsUnicodeMap) {\n      if (glyphsUnicodeMap[key] === unicode) {\n        return key;\n      }\n    }\n  }\n  info(\"Unable to recover a standard glyph name for: \" + name);\n  return name;\n}\nfunction type1FontGlyphMapping(properties, builtInEncoding, glyphNames) {\n  const charCodeToGlyphId = Object.create(null);\n  let glyphId, charCode, baseEncoding;\n  const isSymbolicFont = !!(properties.flags & FontFlags.Symbolic);\n  if (properties.isInternalFont) {\n    baseEncoding = builtInEncoding;\n    for (charCode = 0; charCode < baseEncoding.length; charCode++) {\n      glyphId = glyphNames.indexOf(baseEncoding[charCode]);\n      charCodeToGlyphId[charCode] = glyphId >= 0 ? glyphId : 0;\n    }\n  } else if (properties.baseEncodingName) {\n    baseEncoding = getEncoding(properties.baseEncodingName);\n    for (charCode = 0; charCode < baseEncoding.length; charCode++) {\n      glyphId = glyphNames.indexOf(baseEncoding[charCode]);\n      charCodeToGlyphId[charCode] = glyphId >= 0 ? glyphId : 0;\n    }\n  } else if (isSymbolicFont) {\n    for (charCode in builtInEncoding) {\n      charCodeToGlyphId[charCode] = builtInEncoding[charCode];\n    }\n  } else {\n    baseEncoding = StandardEncoding;\n    for (charCode = 0; charCode < baseEncoding.length; charCode++) {\n      glyphId = glyphNames.indexOf(baseEncoding[charCode]);\n      charCodeToGlyphId[charCode] = glyphId >= 0 ? glyphId : 0;\n    }\n  }\n  const differences = properties.differences;\n  let glyphsUnicodeMap;\n  if (differences) {\n    for (charCode in differences) {\n      const glyphName = differences[charCode];\n      glyphId = glyphNames.indexOf(glyphName);\n      if (glyphId === -1) {\n        if (!glyphsUnicodeMap) {\n          glyphsUnicodeMap = getGlyphsUnicode();\n        }\n        const standardGlyphName = recoverGlyphName(glyphName, glyphsUnicodeMap);\n        if (standardGlyphName !== glyphName) {\n          glyphId = glyphNames.indexOf(standardGlyphName);\n        }\n      }\n      charCodeToGlyphId[charCode] = glyphId >= 0 ? glyphId : 0;\n    }\n  }\n  return charCodeToGlyphId;\n}\nfunction normalizeFontName(name) {\n  return name.replaceAll(/[,_]/g, \"-\").replaceAll(/\\s/g, \"\");\n}\n\n;// ./src/core/standard_fonts.js\n\n\nconst getStdFontMap = getLookupTableFactory(function (t) {\n  t[\"Times-Roman\"] = \"Times-Roman\";\n  t.Helvetica = \"Helvetica\";\n  t.Courier = \"Courier\";\n  t.Symbol = \"Symbol\";\n  t[\"Times-Bold\"] = \"Times-Bold\";\n  t[\"Helvetica-Bold\"] = \"Helvetica-Bold\";\n  t[\"Courier-Bold\"] = \"Courier-Bold\";\n  t.ZapfDingbats = \"ZapfDingbats\";\n  t[\"Times-Italic\"] = \"Times-Italic\";\n  t[\"Helvetica-Oblique\"] = \"Helvetica-Oblique\";\n  t[\"Courier-Oblique\"] = \"Courier-Oblique\";\n  t[\"Times-BoldItalic\"] = \"Times-BoldItalic\";\n  t[\"Helvetica-BoldOblique\"] = \"Helvetica-BoldOblique\";\n  t[\"Courier-BoldOblique\"] = \"Courier-BoldOblique\";\n  t.ArialNarrow = \"Helvetica\";\n  t[\"ArialNarrow-Bold\"] = \"Helvetica-Bold\";\n  t[\"ArialNarrow-BoldItalic\"] = \"Helvetica-BoldOblique\";\n  t[\"ArialNarrow-Italic\"] = \"Helvetica-Oblique\";\n  t.ArialBlack = \"Helvetica\";\n  t[\"ArialBlack-Bold\"] = \"Helvetica-Bold\";\n  t[\"ArialBlack-BoldItalic\"] = \"Helvetica-BoldOblique\";\n  t[\"ArialBlack-Italic\"] = \"Helvetica-Oblique\";\n  t[\"Arial-Black\"] = \"Helvetica\";\n  t[\"Arial-Black-Bold\"] = \"Helvetica-Bold\";\n  t[\"Arial-Black-BoldItalic\"] = \"Helvetica-BoldOblique\";\n  t[\"Arial-Black-Italic\"] = \"Helvetica-Oblique\";\n  t.Arial = \"Helvetica\";\n  t[\"Arial-Bold\"] = \"Helvetica-Bold\";\n  t[\"Arial-BoldItalic\"] = \"Helvetica-BoldOblique\";\n  t[\"Arial-Italic\"] = \"Helvetica-Oblique\";\n  t.ArialMT = \"Helvetica\";\n  t[\"Arial-BoldItalicMT\"] = \"Helvetica-BoldOblique\";\n  t[\"Arial-BoldMT\"] = \"Helvetica-Bold\";\n  t[\"Arial-ItalicMT\"] = \"Helvetica-Oblique\";\n  t[\"Arial-BoldItalicMT-BoldItalic\"] = \"Helvetica-BoldOblique\";\n  t[\"Arial-BoldMT-Bold\"] = \"Helvetica-Bold\";\n  t[\"Arial-ItalicMT-Italic\"] = \"Helvetica-Oblique\";\n  t.ArialUnicodeMS = \"Helvetica\";\n  t[\"ArialUnicodeMS-Bold\"] = \"Helvetica-Bold\";\n  t[\"ArialUnicodeMS-BoldItalic\"] = \"Helvetica-BoldOblique\";\n  t[\"ArialUnicodeMS-Italic\"] = \"Helvetica-Oblique\";\n  t[\"Courier-BoldItalic\"] = \"Courier-BoldOblique\";\n  t[\"Courier-Italic\"] = \"Courier-Oblique\";\n  t.CourierNew = \"Courier\";\n  t[\"CourierNew-Bold\"] = \"Courier-Bold\";\n  t[\"CourierNew-BoldItalic\"] = \"Courier-BoldOblique\";\n  t[\"CourierNew-Italic\"] = \"Courier-Oblique\";\n  t[\"CourierNewPS-BoldItalicMT\"] = \"Courier-BoldOblique\";\n  t[\"CourierNewPS-BoldMT\"] = \"Courier-Bold\";\n  t[\"CourierNewPS-ItalicMT\"] = \"Courier-Oblique\";\n  t.CourierNewPSMT = \"Courier\";\n  t[\"Helvetica-BoldItalic\"] = \"Helvetica-BoldOblique\";\n  t[\"Helvetica-Italic\"] = \"Helvetica-Oblique\";\n  t[\"Symbol-Bold\"] = \"Symbol\";\n  t[\"Symbol-BoldItalic\"] = \"Symbol\";\n  t[\"Symbol-Italic\"] = \"Symbol\";\n  t.TimesNewRoman = \"Times-Roman\";\n  t[\"TimesNewRoman-Bold\"] = \"Times-Bold\";\n  t[\"TimesNewRoman-BoldItalic\"] = \"Times-BoldItalic\";\n  t[\"TimesNewRoman-Italic\"] = \"Times-Italic\";\n  t.TimesNewRomanPS = \"Times-Roman\";\n  t[\"TimesNewRomanPS-Bold\"] = \"Times-Bold\";\n  t[\"TimesNewRomanPS-BoldItalic\"] = \"Times-BoldItalic\";\n  t[\"TimesNewRomanPS-BoldItalicMT\"] = \"Times-BoldItalic\";\n  t[\"TimesNewRomanPS-BoldMT\"] = \"Times-Bold\";\n  t[\"TimesNewRomanPS-Italic\"] = \"Times-Italic\";\n  t[\"TimesNewRomanPS-ItalicMT\"] = \"Times-Italic\";\n  t.TimesNewRomanPSMT = \"Times-Roman\";\n  t[\"TimesNewRomanPSMT-Bold\"] = \"Times-Bold\";\n  t[\"TimesNewRomanPSMT-BoldItalic\"] = \"Times-BoldItalic\";\n  t[\"TimesNewRomanPSMT-Italic\"] = \"Times-Italic\";\n});\nconst getFontNameToFileMap = getLookupTableFactory(function (t) {\n  t.Courier = \"FoxitFixed.pfb\";\n  t[\"Courier-Bold\"] = \"FoxitFixedBold.pfb\";\n  t[\"Courier-BoldOblique\"] = \"FoxitFixedBoldItalic.pfb\";\n  t[\"Courier-Oblique\"] = \"FoxitFixedItalic.pfb\";\n  t.Helvetica = \"LiberationSans-Regular.ttf\";\n  t[\"Helvetica-Bold\"] = \"LiberationSans-Bold.ttf\";\n  t[\"Helvetica-BoldOblique\"] = \"LiberationSans-BoldItalic.ttf\";\n  t[\"Helvetica-Oblique\"] = \"LiberationSans-Italic.ttf\";\n  t[\"Times-Roman\"] = \"FoxitSerif.pfb\";\n  t[\"Times-Bold\"] = \"FoxitSerifBold.pfb\";\n  t[\"Times-BoldItalic\"] = \"FoxitSerifBoldItalic.pfb\";\n  t[\"Times-Italic\"] = \"FoxitSerifItalic.pfb\";\n  t.Symbol = \"FoxitSymbol.pfb\";\n  t.ZapfDingbats = \"FoxitDingbats.pfb\";\n  t[\"LiberationSans-Regular\"] = \"LiberationSans-Regular.ttf\";\n  t[\"LiberationSans-Bold\"] = \"LiberationSans-Bold.ttf\";\n  t[\"LiberationSans-Italic\"] = \"LiberationSans-Italic.ttf\";\n  t[\"LiberationSans-BoldItalic\"] = \"LiberationSans-BoldItalic.ttf\";\n});\nconst getNonStdFontMap = getLookupTableFactory(function (t) {\n  t.Calibri = \"Helvetica\";\n  t[\"Calibri-Bold\"] = \"Helvetica-Bold\";\n  t[\"Calibri-BoldItalic\"] = \"Helvetica-BoldOblique\";\n  t[\"Calibri-Italic\"] = \"Helvetica-Oblique\";\n  t.CenturyGothic = \"Helvetica\";\n  t[\"CenturyGothic-Bold\"] = \"Helvetica-Bold\";\n  t[\"CenturyGothic-BoldItalic\"] = \"Helvetica-BoldOblique\";\n  t[\"CenturyGothic-Italic\"] = \"Helvetica-Oblique\";\n  t.ComicSansMS = \"Comic Sans MS\";\n  t[\"ComicSansMS-Bold\"] = \"Comic Sans MS-Bold\";\n  t[\"ComicSansMS-BoldItalic\"] = \"Comic Sans MS-BoldItalic\";\n  t[\"ComicSansMS-Italic\"] = \"Comic Sans MS-Italic\";\n  t.Impact = \"Helvetica\";\n  t[\"ItcSymbol-Bold\"] = \"Helvetica-Bold\";\n  t[\"ItcSymbol-BoldItalic\"] = \"Helvetica-BoldOblique\";\n  t[\"ItcSymbol-Book\"] = \"Helvetica\";\n  t[\"ItcSymbol-BookItalic\"] = \"Helvetica-Oblique\";\n  t[\"ItcSymbol-Medium\"] = \"Helvetica\";\n  t[\"ItcSymbol-MediumItalic\"] = \"Helvetica-Oblique\";\n  t.LucidaConsole = \"Courier\";\n  t[\"LucidaConsole-Bold\"] = \"Courier-Bold\";\n  t[\"LucidaConsole-BoldItalic\"] = \"Courier-BoldOblique\";\n  t[\"LucidaConsole-Italic\"] = \"Courier-Oblique\";\n  t[\"LucidaSans-Demi\"] = \"Helvetica-Bold\";\n  t[\"MS-Gothic\"] = \"MS Gothic\";\n  t[\"MS-Gothic-Bold\"] = \"MS Gothic-Bold\";\n  t[\"MS-Gothic-BoldItalic\"] = \"MS Gothic-BoldItalic\";\n  t[\"MS-Gothic-Italic\"] = \"MS Gothic-Italic\";\n  t[\"MS-Mincho\"] = \"MS Mincho\";\n  t[\"MS-Mincho-Bold\"] = \"MS Mincho-Bold\";\n  t[\"MS-Mincho-BoldItalic\"] = \"MS Mincho-BoldItalic\";\n  t[\"MS-Mincho-Italic\"] = \"MS Mincho-Italic\";\n  t[\"MS-PGothic\"] = \"MS PGothic\";\n  t[\"MS-PGothic-Bold\"] = \"MS PGothic-Bold\";\n  t[\"MS-PGothic-BoldItalic\"] = \"MS PGothic-BoldItalic\";\n  t[\"MS-PGothic-Italic\"] = \"MS PGothic-Italic\";\n  t[\"MS-PMincho\"] = \"MS PMincho\";\n  t[\"MS-PMincho-Bold\"] = \"MS PMincho-Bold\";\n  t[\"MS-PMincho-BoldItalic\"] = \"MS PMincho-BoldItalic\";\n  t[\"MS-PMincho-Italic\"] = \"MS PMincho-Italic\";\n  t.NuptialScript = \"Times-Italic\";\n  t.SegoeUISymbol = \"Helvetica\";\n});\nconst getSerifFonts = getLookupTableFactory(function (t) {\n  t[\"Adobe Jenson\"] = true;\n  t[\"Adobe Text\"] = true;\n  t.Albertus = true;\n  t.Aldus = true;\n  t.Alexandria = true;\n  t.Algerian = true;\n  t[\"American Typewriter\"] = true;\n  t.Antiqua = true;\n  t.Apex = true;\n  t.Arno = true;\n  t.Aster = true;\n  t.Aurora = true;\n  t.Baskerville = true;\n  t.Bell = true;\n  t.Bembo = true;\n  t[\"Bembo Schoolbook\"] = true;\n  t.Benguiat = true;\n  t[\"Berkeley Old Style\"] = true;\n  t[\"Bernhard Modern\"] = true;\n  t[\"Berthold City\"] = true;\n  t.Bodoni = true;\n  t[\"Bauer Bodoni\"] = true;\n  t[\"Book Antiqua\"] = true;\n  t.Bookman = true;\n  t[\"Bordeaux Roman\"] = true;\n  t[\"Californian FB\"] = true;\n  t.Calisto = true;\n  t.Calvert = true;\n  t.Capitals = true;\n  t.Cambria = true;\n  t.Cartier = true;\n  t.Caslon = true;\n  t.Catull = true;\n  t.Centaur = true;\n  t[\"Century Old Style\"] = true;\n  t[\"Century Schoolbook\"] = true;\n  t.Chaparral = true;\n  t[\"Charis SIL\"] = true;\n  t.Cheltenham = true;\n  t[\"Cholla Slab\"] = true;\n  t.Clarendon = true;\n  t.Clearface = true;\n  t.Cochin = true;\n  t.Colonna = true;\n  t[\"Computer Modern\"] = true;\n  t[\"Concrete Roman\"] = true;\n  t.Constantia = true;\n  t[\"Cooper Black\"] = true;\n  t.Corona = true;\n  t.Ecotype = true;\n  t.Egyptienne = true;\n  t.Elephant = true;\n  t.Excelsior = true;\n  t.Fairfield = true;\n  t[\"FF Scala\"] = true;\n  t.Folkard = true;\n  t.Footlight = true;\n  t.FreeSerif = true;\n  t[\"Friz Quadrata\"] = true;\n  t.Garamond = true;\n  t.Gentium = true;\n  t.Georgia = true;\n  t.Gloucester = true;\n  t[\"Goudy Old Style\"] = true;\n  t[\"Goudy Schoolbook\"] = true;\n  t[\"Goudy Pro Font\"] = true;\n  t.Granjon = true;\n  t[\"Guardian Egyptian\"] = true;\n  t.Heather = true;\n  t.Hercules = true;\n  t[\"High Tower Text\"] = true;\n  t.Hiroshige = true;\n  t[\"Hoefler Text\"] = true;\n  t[\"Humana Serif\"] = true;\n  t.Imprint = true;\n  t[\"Ionic No. 5\"] = true;\n  t.Janson = true;\n  t.Joanna = true;\n  t.Korinna = true;\n  t.Lexicon = true;\n  t.LiberationSerif = true;\n  t[\"Liberation Serif\"] = true;\n  t[\"Linux Libertine\"] = true;\n  t.Literaturnaya = true;\n  t.Lucida = true;\n  t[\"Lucida Bright\"] = true;\n  t.Melior = true;\n  t.Memphis = true;\n  t.Miller = true;\n  t.Minion = true;\n  t.Modern = true;\n  t[\"Mona Lisa\"] = true;\n  t[\"Mrs Eaves\"] = true;\n  t[\"MS Serif\"] = true;\n  t[\"Museo Slab\"] = true;\n  t[\"New York\"] = true;\n  t[\"Nimbus Roman\"] = true;\n  t[\"NPS Rawlinson Roadway\"] = true;\n  t.NuptialScript = true;\n  t.Palatino = true;\n  t.Perpetua = true;\n  t.Plantin = true;\n  t[\"Plantin Schoolbook\"] = true;\n  t.Playbill = true;\n  t[\"Poor Richard\"] = true;\n  t[\"Rawlinson Roadway\"] = true;\n  t.Renault = true;\n  t.Requiem = true;\n  t.Rockwell = true;\n  t.Roman = true;\n  t[\"Rotis Serif\"] = true;\n  t.Sabon = true;\n  t.Scala = true;\n  t.Seagull = true;\n  t.Sistina = true;\n  t.Souvenir = true;\n  t.STIX = true;\n  t[\"Stone Informal\"] = true;\n  t[\"Stone Serif\"] = true;\n  t.Sylfaen = true;\n  t.Times = true;\n  t.Trajan = true;\n  t[\"Trinité\"] = true;\n  t[\"Trump Mediaeval\"] = true;\n  t.Utopia = true;\n  t[\"Vale Type\"] = true;\n  t[\"Bitstream Vera\"] = true;\n  t[\"Vera Serif\"] = true;\n  t.Versailles = true;\n  t.Wanted = true;\n  t.Weiss = true;\n  t[\"Wide Latin\"] = true;\n  t.Windsor = true;\n  t.XITS = true;\n});\nconst getSymbolsFonts = getLookupTableFactory(function (t) {\n  t.Dingbats = true;\n  t.Symbol = true;\n  t.ZapfDingbats = true;\n  t.Wingdings = true;\n  t[\"Wingdings-Bold\"] = true;\n  t[\"Wingdings-Regular\"] = true;\n});\nconst getGlyphMapForStandardFonts = getLookupTableFactory(function (t) {\n  t[2] = 10;\n  t[3] = 32;\n  t[4] = 33;\n  t[5] = 34;\n  t[6] = 35;\n  t[7] = 36;\n  t[8] = 37;\n  t[9] = 38;\n  t[10] = 39;\n  t[11] = 40;\n  t[12] = 41;\n  t[13] = 42;\n  t[14] = 43;\n  t[15] = 44;\n  t[16] = 45;\n  t[17] = 46;\n  t[18] = 47;\n  t[19] = 48;\n  t[20] = 49;\n  t[21] = 50;\n  t[22] = 51;\n  t[23] = 52;\n  t[24] = 53;\n  t[25] = 54;\n  t[26] = 55;\n  t[27] = 56;\n  t[28] = 57;\n  t[29] = 58;\n  t[30] = 894;\n  t[31] = 60;\n  t[32] = 61;\n  t[33] = 62;\n  t[34] = 63;\n  t[35] = 64;\n  t[36] = 65;\n  t[37] = 66;\n  t[38] = 67;\n  t[39] = 68;\n  t[40] = 69;\n  t[41] = 70;\n  t[42] = 71;\n  t[43] = 72;\n  t[44] = 73;\n  t[45] = 74;\n  t[46] = 75;\n  t[47] = 76;\n  t[48] = 77;\n  t[49] = 78;\n  t[50] = 79;\n  t[51] = 80;\n  t[52] = 81;\n  t[53] = 82;\n  t[54] = 83;\n  t[55] = 84;\n  t[56] = 85;\n  t[57] = 86;\n  t[58] = 87;\n  t[59] = 88;\n  t[60] = 89;\n  t[61] = 90;\n  t[62] = 91;\n  t[63] = 92;\n  t[64] = 93;\n  t[65] = 94;\n  t[66] = 95;\n  t[67] = 96;\n  t[68] = 97;\n  t[69] = 98;\n  t[70] = 99;\n  t[71] = 100;\n  t[72] = 101;\n  t[73] = 102;\n  t[74] = 103;\n  t[75] = 104;\n  t[76] = 105;\n  t[77] = 106;\n  t[78] = 107;\n  t[79] = 108;\n  t[80] = 109;\n  t[81] = 110;\n  t[82] = 111;\n  t[83] = 112;\n  t[84] = 113;\n  t[85] = 114;\n  t[86] = 115;\n  t[87] = 116;\n  t[88] = 117;\n  t[89] = 118;\n  t[90] = 119;\n  t[91] = 120;\n  t[92] = 121;\n  t[93] = 122;\n  t[94] = 123;\n  t[95] = 124;\n  t[96] = 125;\n  t[97] = 126;\n  t[98] = 196;\n  t[99] = 197;\n  t[100] = 199;\n  t[101] = 201;\n  t[102] = 209;\n  t[103] = 214;\n  t[104] = 220;\n  t[105] = 225;\n  t[106] = 224;\n  t[107] = 226;\n  t[108] = 228;\n  t[109] = 227;\n  t[110] = 229;\n  t[111] = 231;\n  t[112] = 233;\n  t[113] = 232;\n  t[114] = 234;\n  t[115] = 235;\n  t[116] = 237;\n  t[117] = 236;\n  t[118] = 238;\n  t[119] = 239;\n  t[120] = 241;\n  t[121] = 243;\n  t[122] = 242;\n  t[123] = 244;\n  t[124] = 246;\n  t[125] = 245;\n  t[126] = 250;\n  t[127] = 249;\n  t[128] = 251;\n  t[129] = 252;\n  t[130] = 8224;\n  t[131] = 176;\n  t[132] = 162;\n  t[133] = 163;\n  t[134] = 167;\n  t[135] = 8226;\n  t[136] = 182;\n  t[137] = 223;\n  t[138] = 174;\n  t[139] = 169;\n  t[140] = 8482;\n  t[141] = 180;\n  t[142] = 168;\n  t[143] = 8800;\n  t[144] = 198;\n  t[145] = 216;\n  t[146] = 8734;\n  t[147] = 177;\n  t[148] = 8804;\n  t[149] = 8805;\n  t[150] = 165;\n  t[151] = 181;\n  t[152] = 8706;\n  t[153] = 8721;\n  t[154] = 8719;\n  t[156] = 8747;\n  t[157] = 170;\n  t[158] = 186;\n  t[159] = 8486;\n  t[160] = 230;\n  t[161] = 248;\n  t[162] = 191;\n  t[163] = 161;\n  t[164] = 172;\n  t[165] = 8730;\n  t[166] = 402;\n  t[167] = 8776;\n  t[168] = 8710;\n  t[169] = 171;\n  t[170] = 187;\n  t[171] = 8230;\n  t[179] = 8220;\n  t[180] = 8221;\n  t[181] = 8216;\n  t[182] = 8217;\n  t[200] = 193;\n  t[203] = 205;\n  t[207] = 211;\n  t[210] = 218;\n  t[223] = 711;\n  t[224] = 321;\n  t[225] = 322;\n  t[226] = 352;\n  t[227] = 353;\n  t[228] = 381;\n  t[229] = 382;\n  t[233] = 221;\n  t[234] = 253;\n  t[252] = 263;\n  t[253] = 268;\n  t[254] = 269;\n  t[258] = 258;\n  t[260] = 260;\n  t[261] = 261;\n  t[265] = 280;\n  t[266] = 281;\n  t[267] = 282;\n  t[268] = 283;\n  t[269] = 313;\n  t[275] = 323;\n  t[276] = 324;\n  t[278] = 328;\n  t[283] = 344;\n  t[284] = 345;\n  t[285] = 346;\n  t[286] = 347;\n  t[292] = 367;\n  t[295] = 377;\n  t[296] = 378;\n  t[298] = 380;\n  t[305] = 963;\n  t[306] = 964;\n  t[307] = 966;\n  t[308] = 8215;\n  t[309] = 8252;\n  t[310] = 8319;\n  t[311] = 8359;\n  t[312] = 8592;\n  t[313] = 8593;\n  t[337] = 9552;\n  t[493] = 1039;\n  t[494] = 1040;\n  t[672] = 1488;\n  t[673] = 1489;\n  t[674] = 1490;\n  t[675] = 1491;\n  t[676] = 1492;\n  t[677] = 1493;\n  t[678] = 1494;\n  t[679] = 1495;\n  t[680] = 1496;\n  t[681] = 1497;\n  t[682] = 1498;\n  t[683] = 1499;\n  t[684] = 1500;\n  t[685] = 1501;\n  t[686] = 1502;\n  t[687] = 1503;\n  t[688] = 1504;\n  t[689] = 1505;\n  t[690] = 1506;\n  t[691] = 1507;\n  t[692] = 1508;\n  t[693] = 1509;\n  t[694] = 1510;\n  t[695] = 1511;\n  t[696] = 1512;\n  t[697] = 1513;\n  t[698] = 1514;\n  t[705] = 1524;\n  t[706] = 8362;\n  t[710] = 64288;\n  t[711] = 64298;\n  t[759] = 1617;\n  t[761] = 1776;\n  t[763] = 1778;\n  t[775] = 1652;\n  t[777] = 1764;\n  t[778] = 1780;\n  t[779] = 1781;\n  t[780] = 1782;\n  t[782] = 771;\n  t[783] = 64726;\n  t[786] = 8363;\n  t[788] = 8532;\n  t[790] = 768;\n  t[791] = 769;\n  t[792] = 768;\n  t[795] = 803;\n  t[797] = 64336;\n  t[798] = 64337;\n  t[799] = 64342;\n  t[800] = 64343;\n  t[801] = 64344;\n  t[802] = 64345;\n  t[803] = 64362;\n  t[804] = 64363;\n  t[805] = 64364;\n  t[2424] = 7821;\n  t[2425] = 7822;\n  t[2426] = 7823;\n  t[2427] = 7824;\n  t[2428] = 7825;\n  t[2429] = 7826;\n  t[2430] = 7827;\n  t[2433] = 7682;\n  t[2678] = 8045;\n  t[2679] = 8046;\n  t[2830] = 1552;\n  t[2838] = 686;\n  t[2840] = 751;\n  t[2842] = 753;\n  t[2843] = 754;\n  t[2844] = 755;\n  t[2846] = 757;\n  t[2856] = 767;\n  t[2857] = 848;\n  t[2858] = 849;\n  t[2862] = 853;\n  t[2863] = 854;\n  t[2864] = 855;\n  t[2865] = 861;\n  t[2866] = 862;\n  t[2906] = 7460;\n  t[2908] = 7462;\n  t[2909] = 7463;\n  t[2910] = 7464;\n  t[2912] = 7466;\n  t[2913] = 7467;\n  t[2914] = 7468;\n  t[2916] = 7470;\n  t[2917] = 7471;\n  t[2918] = 7472;\n  t[2920] = 7474;\n  t[2921] = 7475;\n  t[2922] = 7476;\n  t[2924] = 7478;\n  t[2925] = 7479;\n  t[2926] = 7480;\n  t[2928] = 7482;\n  t[2929] = 7483;\n  t[2930] = 7484;\n  t[2932] = 7486;\n  t[2933] = 7487;\n  t[2934] = 7488;\n  t[2936] = 7490;\n  t[2937] = 7491;\n  t[2938] = 7492;\n  t[2940] = 7494;\n  t[2941] = 7495;\n  t[2942] = 7496;\n  t[2944] = 7498;\n  t[2946] = 7500;\n  t[2948] = 7502;\n  t[2950] = 7504;\n  t[2951] = 7505;\n  t[2952] = 7506;\n  t[2954] = 7508;\n  t[2955] = 7509;\n  t[2956] = 7510;\n  t[2958] = 7512;\n  t[2959] = 7513;\n  t[2960] = 7514;\n  t[2962] = 7516;\n  t[2963] = 7517;\n  t[2964] = 7518;\n  t[2966] = 7520;\n  t[2967] = 7521;\n  t[2968] = 7522;\n  t[2970] = 7524;\n  t[2971] = 7525;\n  t[2972] = 7526;\n  t[2974] = 7528;\n  t[2975] = 7529;\n  t[2976] = 7530;\n  t[2978] = 1537;\n  t[2979] = 1538;\n  t[2980] = 1539;\n  t[2982] = 1549;\n  t[2983] = 1551;\n  t[2984] = 1552;\n  t[2986] = 1554;\n  t[2987] = 1555;\n  t[2988] = 1556;\n  t[2990] = 1623;\n  t[2991] = 1624;\n  t[2995] = 1775;\n  t[2999] = 1791;\n  t[3002] = 64290;\n  t[3003] = 64291;\n  t[3004] = 64292;\n  t[3006] = 64294;\n  t[3007] = 64295;\n  t[3008] = 64296;\n  t[3011] = 1900;\n  t[3014] = 8223;\n  t[3015] = 8244;\n  t[3017] = 7532;\n  t[3018] = 7533;\n  t[3019] = 7534;\n  t[3075] = 7590;\n  t[3076] = 7591;\n  t[3079] = 7594;\n  t[3080] = 7595;\n  t[3083] = 7598;\n  t[3084] = 7599;\n  t[3087] = 7602;\n  t[3088] = 7603;\n  t[3091] = 7606;\n  t[3092] = 7607;\n  t[3095] = 7610;\n  t[3096] = 7611;\n  t[3099] = 7614;\n  t[3100] = 7615;\n  t[3103] = 7618;\n  t[3104] = 7619;\n  t[3107] = 8337;\n  t[3108] = 8338;\n  t[3116] = 1884;\n  t[3119] = 1885;\n  t[3120] = 1885;\n  t[3123] = 1886;\n  t[3124] = 1886;\n  t[3127] = 1887;\n  t[3128] = 1887;\n  t[3131] = 1888;\n  t[3132] = 1888;\n  t[3135] = 1889;\n  t[3136] = 1889;\n  t[3139] = 1890;\n  t[3140] = 1890;\n  t[3143] = 1891;\n  t[3144] = 1891;\n  t[3147] = 1892;\n  t[3148] = 1892;\n  t[3153] = 580;\n  t[3154] = 581;\n  t[3157] = 584;\n  t[3158] = 585;\n  t[3161] = 588;\n  t[3162] = 589;\n  t[3165] = 891;\n  t[3166] = 892;\n  t[3169] = 1274;\n  t[3170] = 1275;\n  t[3173] = 1278;\n  t[3174] = 1279;\n  t[3181] = 7622;\n  t[3182] = 7623;\n  t[3282] = 11799;\n  t[3316] = 578;\n  t[3379] = 42785;\n  t[3393] = 1159;\n  t[3416] = 8377;\n});\nconst getSupplementalGlyphMapForArialBlack = getLookupTableFactory(function (t) {\n  t[227] = 322;\n  t[264] = 261;\n  t[291] = 346;\n});\nconst getSupplementalGlyphMapForCalibri = getLookupTableFactory(function (t) {\n  t[1] = 32;\n  t[4] = 65;\n  t[5] = 192;\n  t[6] = 193;\n  t[9] = 196;\n  t[17] = 66;\n  t[18] = 67;\n  t[21] = 268;\n  t[24] = 68;\n  t[28] = 69;\n  t[29] = 200;\n  t[30] = 201;\n  t[32] = 282;\n  t[38] = 70;\n  t[39] = 71;\n  t[44] = 72;\n  t[47] = 73;\n  t[48] = 204;\n  t[49] = 205;\n  t[58] = 74;\n  t[60] = 75;\n  t[62] = 76;\n  t[68] = 77;\n  t[69] = 78;\n  t[75] = 79;\n  t[76] = 210;\n  t[80] = 214;\n  t[87] = 80;\n  t[89] = 81;\n  t[90] = 82;\n  t[92] = 344;\n  t[94] = 83;\n  t[97] = 352;\n  t[100] = 84;\n  t[104] = 85;\n  t[109] = 220;\n  t[115] = 86;\n  t[116] = 87;\n  t[121] = 88;\n  t[122] = 89;\n  t[124] = 221;\n  t[127] = 90;\n  t[129] = 381;\n  t[258] = 97;\n  t[259] = 224;\n  t[260] = 225;\n  t[263] = 228;\n  t[268] = 261;\n  t[271] = 98;\n  t[272] = 99;\n  t[273] = 263;\n  t[275] = 269;\n  t[282] = 100;\n  t[286] = 101;\n  t[287] = 232;\n  t[288] = 233;\n  t[290] = 283;\n  t[295] = 281;\n  t[296] = 102;\n  t[336] = 103;\n  t[346] = 104;\n  t[349] = 105;\n  t[350] = 236;\n  t[351] = 237;\n  t[361] = 106;\n  t[364] = 107;\n  t[367] = 108;\n  t[371] = 322;\n  t[373] = 109;\n  t[374] = 110;\n  t[381] = 111;\n  t[382] = 242;\n  t[383] = 243;\n  t[386] = 246;\n  t[393] = 112;\n  t[395] = 113;\n  t[396] = 114;\n  t[398] = 345;\n  t[400] = 115;\n  t[401] = 347;\n  t[403] = 353;\n  t[410] = 116;\n  t[437] = 117;\n  t[442] = 252;\n  t[448] = 118;\n  t[449] = 119;\n  t[454] = 120;\n  t[455] = 121;\n  t[457] = 253;\n  t[460] = 122;\n  t[462] = 382;\n  t[463] = 380;\n  t[853] = 44;\n  t[855] = 58;\n  t[856] = 46;\n  t[876] = 47;\n  t[878] = 45;\n  t[882] = 45;\n  t[894] = 40;\n  t[895] = 41;\n  t[896] = 91;\n  t[897] = 93;\n  t[923] = 64;\n  t[1004] = 48;\n  t[1005] = 49;\n  t[1006] = 50;\n  t[1007] = 51;\n  t[1008] = 52;\n  t[1009] = 53;\n  t[1010] = 54;\n  t[1011] = 55;\n  t[1012] = 56;\n  t[1013] = 57;\n  t[1081] = 37;\n  t[1085] = 43;\n  t[1086] = 45;\n});\nfunction getStandardFontName(name) {\n  const fontName = normalizeFontName(name);\n  const stdFontMap = getStdFontMap();\n  return stdFontMap[fontName];\n}\nfunction isKnownFontName(name) {\n  const fontName = normalizeFontName(name);\n  return !!(getStdFontMap()[fontName] || getNonStdFontMap()[fontName] || getSerifFonts()[fontName] || getSymbolsFonts()[fontName]);\n}\n\n;// ./src/core/to_unicode_map.js\n\nclass ToUnicodeMap {\n  constructor(cmap = []) {\n    this._map = cmap;\n  }\n  get length() {\n    return this._map.length;\n  }\n  forEach(callback) {\n    for (const charCode in this._map) {\n      callback(charCode, this._map[charCode].charCodeAt(0));\n    }\n  }\n  has(i) {\n    return this._map[i] !== undefined;\n  }\n  get(i) {\n    return this._map[i];\n  }\n  charCodeOf(value) {\n    const map = this._map;\n    if (map.length <= 0x10000) {\n      return map.indexOf(value);\n    }\n    for (const charCode in map) {\n      if (map[charCode] === value) {\n        return charCode | 0;\n      }\n    }\n    return -1;\n  }\n  amend(map) {\n    for (const charCode in map) {\n      this._map[charCode] = map[charCode];\n    }\n  }\n}\nclass IdentityToUnicodeMap {\n  constructor(firstChar, lastChar) {\n    this.firstChar = firstChar;\n    this.lastChar = lastChar;\n  }\n  get length() {\n    return this.lastChar + 1 - this.firstChar;\n  }\n  forEach(callback) {\n    for (let i = this.firstChar, ii = this.lastChar; i <= ii; i++) {\n      callback(i, i);\n    }\n  }\n  has(i) {\n    return this.firstChar <= i && i <= this.lastChar;\n  }\n  get(i) {\n    if (this.firstChar <= i && i <= this.lastChar) {\n      return String.fromCharCode(i);\n    }\n    return undefined;\n  }\n  charCodeOf(v) {\n    return Number.isInteger(v) && v >= this.firstChar && v <= this.lastChar ? v : -1;\n  }\n  amend(map) {\n    unreachable(\"Should not call amend()\");\n  }\n}\n\n;// ./src/core/cff_font.js\n\n\n\nclass CFFFont {\n  constructor(file, properties) {\n    this.properties = properties;\n    const parser = new CFFParser(file, properties, SEAC_ANALYSIS_ENABLED);\n    this.cff = parser.parse();\n    this.cff.duplicateFirstGlyph();\n    const compiler = new CFFCompiler(this.cff);\n    this.seacs = this.cff.seacs;\n    try {\n      this.data = compiler.compile();\n    } catch {\n      warn(\"Failed to compile font \" + properties.loadedName);\n      this.data = file;\n    }\n    this._createBuiltInEncoding();\n  }\n  get numGlyphs() {\n    return this.cff.charStrings.count;\n  }\n  getCharset() {\n    return this.cff.charset.charset;\n  }\n  getGlyphMapping() {\n    const cff = this.cff;\n    const properties = this.properties;\n    const {\n      cidToGidMap,\n      cMap\n    } = properties;\n    const charsets = cff.charset.charset;\n    let charCodeToGlyphId;\n    let glyphId;\n    if (properties.composite) {\n      let invCidToGidMap;\n      if (cidToGidMap?.length > 0) {\n        invCidToGidMap = Object.create(null);\n        for (let i = 0, ii = cidToGidMap.length; i < ii; i++) {\n          const gid = cidToGidMap[i];\n          if (gid !== undefined) {\n            invCidToGidMap[gid] = i;\n          }\n        }\n      }\n      charCodeToGlyphId = Object.create(null);\n      let charCode;\n      if (cff.isCIDFont) {\n        for (glyphId = 0; glyphId < charsets.length; glyphId++) {\n          const cid = charsets[glyphId];\n          charCode = cMap.charCodeOf(cid);\n          if (invCidToGidMap?.[charCode] !== undefined) {\n            charCode = invCidToGidMap[charCode];\n          }\n          charCodeToGlyphId[charCode] = glyphId;\n        }\n      } else {\n        for (glyphId = 0; glyphId < cff.charStrings.count; glyphId++) {\n          charCode = cMap.charCodeOf(glyphId);\n          charCodeToGlyphId[charCode] = glyphId;\n        }\n      }\n      return charCodeToGlyphId;\n    }\n    let encoding = cff.encoding ? cff.encoding.encoding : null;\n    if (properties.isInternalFont) {\n      encoding = properties.defaultEncoding;\n    }\n    charCodeToGlyphId = type1FontGlyphMapping(properties, encoding, charsets);\n    return charCodeToGlyphId;\n  }\n  hasGlyphId(id) {\n    return this.cff.hasGlyphId(id);\n  }\n  _createBuiltInEncoding() {\n    const {\n      charset,\n      encoding\n    } = this.cff;\n    if (!charset || !encoding) {\n      return;\n    }\n    const charsets = charset.charset,\n      encodings = encoding.encoding;\n    const map = [];\n    for (const charCode in encodings) {\n      const glyphId = encodings[charCode];\n      if (glyphId >= 0) {\n        const glyphName = charsets[glyphId];\n        if (glyphName) {\n          map[charCode] = glyphName;\n        }\n      }\n    }\n    if (map.length > 0) {\n      this.properties.builtInEncoding = map;\n    }\n  }\n}\n\n;// ./src/core/font_renderer.js\n\n\n\n\n\nfunction getUint32(data, offset) {\n  return (data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]) >>> 0;\n}\nfunction getUint16(data, offset) {\n  return data[offset] << 8 | data[offset + 1];\n}\nfunction getInt16(data, offset) {\n  return (data[offset] << 24 | data[offset + 1] << 16) >> 16;\n}\nfunction getInt8(data, offset) {\n  return data[offset] << 24 >> 24;\n}\nfunction getFloat214(data, offset) {\n  return getInt16(data, offset) / 16384;\n}\nfunction getSubroutineBias(subrs) {\n  const numSubrs = subrs.length;\n  let bias = 32768;\n  if (numSubrs < 1240) {\n    bias = 107;\n  } else if (numSubrs < 33900) {\n    bias = 1131;\n  }\n  return bias;\n}\nfunction parseCmap(data, start, end) {\n  const offset = getUint16(data, start + 2) === 1 ? getUint32(data, start + 8) : getUint32(data, start + 16);\n  const format = getUint16(data, start + offset);\n  let ranges, p, i;\n  if (format === 4) {\n    getUint16(data, start + offset + 2);\n    const segCount = getUint16(data, start + offset + 6) >> 1;\n    p = start + offset + 14;\n    ranges = [];\n    for (i = 0; i < segCount; i++, p += 2) {\n      ranges[i] = {\n        end: getUint16(data, p)\n      };\n    }\n    p += 2;\n    for (i = 0; i < segCount; i++, p += 2) {\n      ranges[i].start = getUint16(data, p);\n    }\n    for (i = 0; i < segCount; i++, p += 2) {\n      ranges[i].idDelta = getUint16(data, p);\n    }\n    for (i = 0; i < segCount; i++, p += 2) {\n      let idOffset = getUint16(data, p);\n      if (idOffset === 0) {\n        continue;\n      }\n      ranges[i].ids = [];\n      for (let j = 0, jj = ranges[i].end - ranges[i].start + 1; j < jj; j++) {\n        ranges[i].ids[j] = getUint16(data, p + idOffset);\n        idOffset += 2;\n      }\n    }\n    return ranges;\n  } else if (format === 12) {\n    const groups = getUint32(data, start + offset + 12);\n    p = start + offset + 16;\n    ranges = [];\n    for (i = 0; i < groups; i++) {\n      start = getUint32(data, p);\n      ranges.push({\n        start,\n        end: getUint32(data, p + 4),\n        idDelta: getUint32(data, p + 8) - start\n      });\n      p += 12;\n    }\n    return ranges;\n  }\n  throw new FormatError(`unsupported cmap: ${format}`);\n}\nfunction parseCff(data, start, end, seacAnalysisEnabled) {\n  const properties = {};\n  const parser = new CFFParser(new Stream(data, start, end - start), properties, seacAnalysisEnabled);\n  const cff = parser.parse();\n  return {\n    glyphs: cff.charStrings.objects,\n    subrs: cff.topDict.privateDict?.subrsIndex?.objects,\n    gsubrs: cff.globalSubrIndex?.objects,\n    isCFFCIDFont: cff.isCIDFont,\n    fdSelect: cff.fdSelect,\n    fdArray: cff.fdArray\n  };\n}\nfunction parseGlyfTable(glyf, loca, isGlyphLocationsLong) {\n  let itemSize, itemDecode;\n  if (isGlyphLocationsLong) {\n    itemSize = 4;\n    itemDecode = getUint32;\n  } else {\n    itemSize = 2;\n    itemDecode = (data, offset) => 2 * getUint16(data, offset);\n  }\n  const glyphs = [];\n  let startOffset = itemDecode(loca, 0);\n  for (let j = itemSize; j < loca.length; j += itemSize) {\n    const endOffset = itemDecode(loca, j);\n    glyphs.push(glyf.subarray(startOffset, endOffset));\n    startOffset = endOffset;\n  }\n  return glyphs;\n}\nfunction lookupCmap(ranges, unicode) {\n  const code = unicode.codePointAt(0);\n  let gid = 0,\n    l = 0,\n    r = ranges.length - 1;\n  while (l < r) {\n    const c = l + r + 1 >> 1;\n    if (code < ranges[c].start) {\n      r = c - 1;\n    } else {\n      l = c;\n    }\n  }\n  if (ranges[l].start <= code && code <= ranges[l].end) {\n    gid = ranges[l].idDelta + (ranges[l].ids ? ranges[l].ids[code - ranges[l].start] : code) & 0xffff;\n  }\n  return {\n    charCode: code,\n    glyphId: gid\n  };\n}\nfunction compileGlyf(code, cmds, font) {\n  function moveTo(x, y) {\n    cmds.push({\n      cmd: \"moveTo\",\n      args: [x, y]\n    });\n  }\n  function lineTo(x, y) {\n    cmds.push({\n      cmd: \"lineTo\",\n      args: [x, y]\n    });\n  }\n  function quadraticCurveTo(xa, ya, x, y) {\n    cmds.push({\n      cmd: \"quadraticCurveTo\",\n      args: [xa, ya, x, y]\n    });\n  }\n  let i = 0;\n  const numberOfContours = getInt16(code, i);\n  let flags;\n  let x = 0,\n    y = 0;\n  i += 10;\n  if (numberOfContours < 0) {\n    do {\n      flags = getUint16(code, i);\n      const glyphIndex = getUint16(code, i + 2);\n      i += 4;\n      let arg1, arg2;\n      if (flags & 0x01) {\n        if (flags & 0x02) {\n          arg1 = getInt16(code, i);\n          arg2 = getInt16(code, i + 2);\n        } else {\n          arg1 = getUint16(code, i);\n          arg2 = getUint16(code, i + 2);\n        }\n        i += 4;\n      } else if (flags & 0x02) {\n        arg1 = getInt8(code, i++);\n        arg2 = getInt8(code, i++);\n      } else {\n        arg1 = code[i++];\n        arg2 = code[i++];\n      }\n      if (flags & 0x02) {\n        x = arg1;\n        y = arg2;\n      } else {\n        x = 0;\n        y = 0;\n      }\n      let scaleX = 1,\n        scaleY = 1,\n        scale01 = 0,\n        scale10 = 0;\n      if (flags & 0x08) {\n        scaleX = scaleY = getFloat214(code, i);\n        i += 2;\n      } else if (flags & 0x40) {\n        scaleX = getFloat214(code, i);\n        scaleY = getFloat214(code, i + 2);\n        i += 4;\n      } else if (flags & 0x80) {\n        scaleX = getFloat214(code, i);\n        scale01 = getFloat214(code, i + 2);\n        scale10 = getFloat214(code, i + 4);\n        scaleY = getFloat214(code, i + 6);\n        i += 8;\n      }\n      const subglyph = font.glyphs[glyphIndex];\n      if (subglyph) {\n        cmds.push({\n          cmd: \"save\"\n        }, {\n          cmd: \"transform\",\n          args: [scaleX, scale01, scale10, scaleY, x, y]\n        });\n        if (!(flags & 0x02)) {}\n        compileGlyf(subglyph, cmds, font);\n        cmds.push({\n          cmd: \"restore\"\n        });\n      }\n    } while (flags & 0x20);\n  } else {\n    const endPtsOfContours = [];\n    let j, jj;\n    for (j = 0; j < numberOfContours; j++) {\n      endPtsOfContours.push(getUint16(code, i));\n      i += 2;\n    }\n    const instructionLength = getUint16(code, i);\n    i += 2 + instructionLength;\n    const numberOfPoints = endPtsOfContours.at(-1) + 1;\n    const points = [];\n    while (points.length < numberOfPoints) {\n      flags = code[i++];\n      let repeat = 1;\n      if (flags & 0x08) {\n        repeat += code[i++];\n      }\n      while (repeat-- > 0) {\n        points.push({\n          flags\n        });\n      }\n    }\n    for (j = 0; j < numberOfPoints; j++) {\n      switch (points[j].flags & 0x12) {\n        case 0x00:\n          x += getInt16(code, i);\n          i += 2;\n          break;\n        case 0x02:\n          x -= code[i++];\n          break;\n        case 0x12:\n          x += code[i++];\n          break;\n      }\n      points[j].x = x;\n    }\n    for (j = 0; j < numberOfPoints; j++) {\n      switch (points[j].flags & 0x24) {\n        case 0x00:\n          y += getInt16(code, i);\n          i += 2;\n          break;\n        case 0x04:\n          y -= code[i++];\n          break;\n        case 0x24:\n          y += code[i++];\n          break;\n      }\n      points[j].y = y;\n    }\n    let startPoint = 0;\n    for (i = 0; i < numberOfContours; i++) {\n      const endPoint = endPtsOfContours[i];\n      const contour = points.slice(startPoint, endPoint + 1);\n      if (contour[0].flags & 1) {\n        contour.push(contour[0]);\n      } else if (contour.at(-1).flags & 1) {\n        contour.unshift(contour.at(-1));\n      } else {\n        const p = {\n          flags: 1,\n          x: (contour[0].x + contour.at(-1).x) / 2,\n          y: (contour[0].y + contour.at(-1).y) / 2\n        };\n        contour.unshift(p);\n        contour.push(p);\n      }\n      moveTo(contour[0].x, contour[0].y);\n      for (j = 1, jj = contour.length; j < jj; j++) {\n        if (contour[j].flags & 1) {\n          lineTo(contour[j].x, contour[j].y);\n        } else if (contour[j + 1].flags & 1) {\n          quadraticCurveTo(contour[j].x, contour[j].y, contour[j + 1].x, contour[j + 1].y);\n          j++;\n        } else {\n          quadraticCurveTo(contour[j].x, contour[j].y, (contour[j].x + contour[j + 1].x) / 2, (contour[j].y + contour[j + 1].y) / 2);\n        }\n      }\n      startPoint = endPoint + 1;\n    }\n  }\n}\nfunction compileCharString(charStringCode, cmds, font, glyphId) {\n  function moveTo(x, y) {\n    cmds.push({\n      cmd: \"moveTo\",\n      args: [x, y]\n    });\n  }\n  function lineTo(x, y) {\n    cmds.push({\n      cmd: \"lineTo\",\n      args: [x, y]\n    });\n  }\n  function bezierCurveTo(x1, y1, x2, y2, x, y) {\n    cmds.push({\n      cmd: \"bezierCurveTo\",\n      args: [x1, y1, x2, y2, x, y]\n    });\n  }\n  const stack = [];\n  let x = 0,\n    y = 0;\n  let stems = 0;\n  function parse(code) {\n    let i = 0;\n    while (i < code.length) {\n      let stackClean = false;\n      let v = code[i++];\n      let xa, xb, ya, yb, y1, y2, y3, n, subrCode;\n      switch (v) {\n        case 1:\n          stems += stack.length >> 1;\n          stackClean = true;\n          break;\n        case 3:\n          stems += stack.length >> 1;\n          stackClean = true;\n          break;\n        case 4:\n          y += stack.pop();\n          moveTo(x, y);\n          stackClean = true;\n          break;\n        case 5:\n          while (stack.length > 0) {\n            x += stack.shift();\n            y += stack.shift();\n            lineTo(x, y);\n          }\n          break;\n        case 6:\n          while (stack.length > 0) {\n            x += stack.shift();\n            lineTo(x, y);\n            if (stack.length === 0) {\n              break;\n            }\n            y += stack.shift();\n            lineTo(x, y);\n          }\n          break;\n        case 7:\n          while (stack.length > 0) {\n            y += stack.shift();\n            lineTo(x, y);\n            if (stack.length === 0) {\n              break;\n            }\n            x += stack.shift();\n            lineTo(x, y);\n          }\n          break;\n        case 8:\n          while (stack.length > 0) {\n            xa = x + stack.shift();\n            ya = y + stack.shift();\n            xb = xa + stack.shift();\n            yb = ya + stack.shift();\n            x = xb + stack.shift();\n            y = yb + stack.shift();\n            bezierCurveTo(xa, ya, xb, yb, x, y);\n          }\n          break;\n        case 10:\n          n = stack.pop();\n          subrCode = null;\n          if (font.isCFFCIDFont) {\n            const fdIndex = font.fdSelect.getFDIndex(glyphId);\n            if (fdIndex >= 0 && fdIndex < font.fdArray.length) {\n              const fontDict = font.fdArray[fdIndex];\n              let subrs;\n              if (fontDict.privateDict?.subrsIndex) {\n                subrs = fontDict.privateDict.subrsIndex.objects;\n              }\n              if (subrs) {\n                n += getSubroutineBias(subrs);\n                subrCode = subrs[n];\n              }\n            } else {\n              warn(\"Invalid fd index for glyph index.\");\n            }\n          } else {\n            subrCode = font.subrs[n + font.subrsBias];\n          }\n          if (subrCode) {\n            parse(subrCode);\n          }\n          break;\n        case 11:\n          return;\n        case 12:\n          v = code[i++];\n          switch (v) {\n            case 34:\n              xa = x + stack.shift();\n              xb = xa + stack.shift();\n              y1 = y + stack.shift();\n              x = xb + stack.shift();\n              bezierCurveTo(xa, y, xb, y1, x, y1);\n              xa = x + stack.shift();\n              xb = xa + stack.shift();\n              x = xb + stack.shift();\n              bezierCurveTo(xa, y1, xb, y, x, y);\n              break;\n            case 35:\n              xa = x + stack.shift();\n              ya = y + stack.shift();\n              xb = xa + stack.shift();\n              yb = ya + stack.shift();\n              x = xb + stack.shift();\n              y = yb + stack.shift();\n              bezierCurveTo(xa, ya, xb, yb, x, y);\n              xa = x + stack.shift();\n              ya = y + stack.shift();\n              xb = xa + stack.shift();\n              yb = ya + stack.shift();\n              x = xb + stack.shift();\n              y = yb + stack.shift();\n              bezierCurveTo(xa, ya, xb, yb, x, y);\n              stack.pop();\n              break;\n            case 36:\n              xa = x + stack.shift();\n              y1 = y + stack.shift();\n              xb = xa + stack.shift();\n              y2 = y1 + stack.shift();\n              x = xb + stack.shift();\n              bezierCurveTo(xa, y1, xb, y2, x, y2);\n              xa = x + stack.shift();\n              xb = xa + stack.shift();\n              y3 = y2 + stack.shift();\n              x = xb + stack.shift();\n              bezierCurveTo(xa, y2, xb, y3, x, y);\n              break;\n            case 37:\n              const x0 = x,\n                y0 = y;\n              xa = x + stack.shift();\n              ya = y + stack.shift();\n              xb = xa + stack.shift();\n              yb = ya + stack.shift();\n              x = xb + stack.shift();\n              y = yb + stack.shift();\n              bezierCurveTo(xa, ya, xb, yb, x, y);\n              xa = x + stack.shift();\n              ya = y + stack.shift();\n              xb = xa + stack.shift();\n              yb = ya + stack.shift();\n              x = xb;\n              y = yb;\n              if (Math.abs(x - x0) > Math.abs(y - y0)) {\n                x += stack.shift();\n              } else {\n                y += stack.shift();\n              }\n              bezierCurveTo(xa, ya, xb, yb, x, y);\n              break;\n            default:\n              throw new FormatError(`unknown operator: 12 ${v}`);\n          }\n          break;\n        case 14:\n          if (stack.length >= 4) {\n            const achar = stack.pop();\n            const bchar = stack.pop();\n            y = stack.pop();\n            x = stack.pop();\n            cmds.push({\n              cmd: \"save\"\n            }, {\n              cmd: \"translate\",\n              args: [x, y]\n            });\n            let cmap = lookupCmap(font.cmap, String.fromCharCode(font.glyphNameMap[StandardEncoding[achar]]));\n            compileCharString(font.glyphs[cmap.glyphId], cmds, font, cmap.glyphId);\n            cmds.push({\n              cmd: \"restore\"\n            });\n            cmap = lookupCmap(font.cmap, String.fromCharCode(font.glyphNameMap[StandardEncoding[bchar]]));\n            compileCharString(font.glyphs[cmap.glyphId], cmds, font, cmap.glyphId);\n          }\n          return;\n        case 18:\n          stems += stack.length >> 1;\n          stackClean = true;\n          break;\n        case 19:\n          stems += stack.length >> 1;\n          i += stems + 7 >> 3;\n          stackClean = true;\n          break;\n        case 20:\n          stems += stack.length >> 1;\n          i += stems + 7 >> 3;\n          stackClean = true;\n          break;\n        case 21:\n          y += stack.pop();\n          x += stack.pop();\n          moveTo(x, y);\n          stackClean = true;\n          break;\n        case 22:\n          x += stack.pop();\n          moveTo(x, y);\n          stackClean = true;\n          break;\n        case 23:\n          stems += stack.length >> 1;\n          stackClean = true;\n          break;\n        case 24:\n          while (stack.length > 2) {\n            xa = x + stack.shift();\n            ya = y + stack.shift();\n            xb = xa + stack.shift();\n            yb = ya + stack.shift();\n            x = xb + stack.shift();\n            y = yb + stack.shift();\n            bezierCurveTo(xa, ya, xb, yb, x, y);\n          }\n          x += stack.shift();\n          y += stack.shift();\n          lineTo(x, y);\n          break;\n        case 25:\n          while (stack.length > 6) {\n            x += stack.shift();\n            y += stack.shift();\n            lineTo(x, y);\n          }\n          xa = x + stack.shift();\n          ya = y + stack.shift();\n          xb = xa + stack.shift();\n          yb = ya + stack.shift();\n          x = xb + stack.shift();\n          y = yb + stack.shift();\n          bezierCurveTo(xa, ya, xb, yb, x, y);\n          break;\n        case 26:\n          if (stack.length % 2) {\n            x += stack.shift();\n          }\n          while (stack.length > 0) {\n            xa = x;\n            ya = y + stack.shift();\n            xb = xa + stack.shift();\n            yb = ya + stack.shift();\n            x = xb;\n            y = yb + stack.shift();\n            bezierCurveTo(xa, ya, xb, yb, x, y);\n          }\n          break;\n        case 27:\n          if (stack.length % 2) {\n            y += stack.shift();\n          }\n          while (stack.length > 0) {\n            xa = x + stack.shift();\n            ya = y;\n            xb = xa + stack.shift();\n            yb = ya + stack.shift();\n            x = xb + stack.shift();\n            y = yb;\n            bezierCurveTo(xa, ya, xb, yb, x, y);\n          }\n          break;\n        case 28:\n          stack.push((code[i] << 24 | code[i + 1] << 16) >> 16);\n          i += 2;\n          break;\n        case 29:\n          n = stack.pop() + font.gsubrsBias;\n          subrCode = font.gsubrs[n];\n          if (subrCode) {\n            parse(subrCode);\n          }\n          break;\n        case 30:\n          while (stack.length > 0) {\n            xa = x;\n            ya = y + stack.shift();\n            xb = xa + stack.shift();\n            yb = ya + stack.shift();\n            x = xb + stack.shift();\n            y = yb + (stack.length === 1 ? stack.shift() : 0);\n            bezierCurveTo(xa, ya, xb, yb, x, y);\n            if (stack.length === 0) {\n              break;\n            }\n            xa = x + stack.shift();\n            ya = y;\n            xb = xa + stack.shift();\n            yb = ya + stack.shift();\n            y = yb + stack.shift();\n            x = xb + (stack.length === 1 ? stack.shift() : 0);\n            bezierCurveTo(xa, ya, xb, yb, x, y);\n          }\n          break;\n        case 31:\n          while (stack.length > 0) {\n            xa = x + stack.shift();\n            ya = y;\n            xb = xa + stack.shift();\n            yb = ya + stack.shift();\n            y = yb + stack.shift();\n            x = xb + (stack.length === 1 ? stack.shift() : 0);\n            bezierCurveTo(xa, ya, xb, yb, x, y);\n            if (stack.length === 0) {\n              break;\n            }\n            xa = x;\n            ya = y + stack.shift();\n            xb = xa + stack.shift();\n            yb = ya + stack.shift();\n            x = xb + stack.shift();\n            y = yb + (stack.length === 1 ? stack.shift() : 0);\n            bezierCurveTo(xa, ya, xb, yb, x, y);\n          }\n          break;\n        default:\n          if (v < 32) {\n            throw new FormatError(`unknown operator: ${v}`);\n          }\n          if (v < 247) {\n            stack.push(v - 139);\n          } else if (v < 251) {\n            stack.push((v - 247) * 256 + code[i++] + 108);\n          } else if (v < 255) {\n            stack.push(-(v - 251) * 256 - code[i++] - 108);\n          } else {\n            stack.push((code[i] << 24 | code[i + 1] << 16 | code[i + 2] << 8 | code[i + 3]) / 65536);\n            i += 4;\n          }\n          break;\n      }\n      if (stackClean) {\n        stack.length = 0;\n      }\n    }\n  }\n  parse(charStringCode);\n}\nconst NOOP = [];\nclass CompiledFont {\n  constructor(fontMatrix) {\n    if (this.constructor === CompiledFont) {\n      unreachable(\"Cannot initialize CompiledFont.\");\n    }\n    this.fontMatrix = fontMatrix;\n    this.compiledGlyphs = Object.create(null);\n    this.compiledCharCodeToGlyphId = Object.create(null);\n  }\n  getPathJs(unicode) {\n    const {\n      charCode,\n      glyphId\n    } = lookupCmap(this.cmap, unicode);\n    let fn = this.compiledGlyphs[glyphId];\n    if (!fn) {\n      try {\n        fn = this.compileGlyph(this.glyphs[glyphId], glyphId);\n        this.compiledGlyphs[glyphId] = fn;\n      } catch (ex) {\n        this.compiledGlyphs[glyphId] = NOOP;\n        if (this.compiledCharCodeToGlyphId[charCode] === undefined) {\n          this.compiledCharCodeToGlyphId[charCode] = glyphId;\n        }\n        throw ex;\n      }\n    }\n    if (this.compiledCharCodeToGlyphId[charCode] === undefined) {\n      this.compiledCharCodeToGlyphId[charCode] = glyphId;\n    }\n    return fn;\n  }\n  compileGlyph(code, glyphId) {\n    if (!code || code.length === 0 || code[0] === 14) {\n      return NOOP;\n    }\n    let fontMatrix = this.fontMatrix;\n    if (this.isCFFCIDFont) {\n      const fdIndex = this.fdSelect.getFDIndex(glyphId);\n      if (fdIndex >= 0 && fdIndex < this.fdArray.length) {\n        const fontDict = this.fdArray[fdIndex];\n        fontMatrix = fontDict.getByName(\"FontMatrix\") || FONT_IDENTITY_MATRIX;\n      } else {\n        warn(\"Invalid fd index for glyph index.\");\n      }\n    }\n    const cmds = [{\n      cmd: \"save\"\n    }, {\n      cmd: \"transform\",\n      args: fontMatrix.slice()\n    }, {\n      cmd: \"scale\",\n      args: [\"size\", \"-size\"]\n    }];\n    this.compileGlyphImpl(code, cmds, glyphId);\n    cmds.push({\n      cmd: \"restore\"\n    });\n    return cmds;\n  }\n  compileGlyphImpl() {\n    unreachable(\"Children classes should implement this.\");\n  }\n  hasBuiltPath(unicode) {\n    const {\n      charCode,\n      glyphId\n    } = lookupCmap(this.cmap, unicode);\n    return this.compiledGlyphs[glyphId] !== undefined && this.compiledCharCodeToGlyphId[charCode] !== undefined;\n  }\n}\nclass TrueTypeCompiled extends CompiledFont {\n  constructor(glyphs, cmap, fontMatrix) {\n    super(fontMatrix || [0.000488, 0, 0, 0.000488, 0, 0]);\n    this.glyphs = glyphs;\n    this.cmap = cmap;\n  }\n  compileGlyphImpl(code, cmds) {\n    compileGlyf(code, cmds, this);\n  }\n}\nclass Type2Compiled extends CompiledFont {\n  constructor(cffInfo, cmap, fontMatrix, glyphNameMap) {\n    super(fontMatrix || [0.001, 0, 0, 0.001, 0, 0]);\n    this.glyphs = cffInfo.glyphs || [];\n    this.gsubrs = cffInfo.gsubrs || [];\n    this.subrs = cffInfo.subrs || [];\n    this.cmap = cmap;\n    this.glyphNameMap = glyphNameMap || getGlyphsUnicode();\n    this.gsubrsBias = getSubroutineBias(this.gsubrs);\n    this.subrsBias = getSubroutineBias(this.subrs);\n    this.isCFFCIDFont = cffInfo.isCFFCIDFont;\n    this.fdSelect = cffInfo.fdSelect;\n    this.fdArray = cffInfo.fdArray;\n  }\n  compileGlyphImpl(code, cmds, glyphId) {\n    compileCharString(code, cmds, this, glyphId);\n  }\n}\nclass FontRendererFactory {\n  static create(font, seacAnalysisEnabled) {\n    const data = new Uint8Array(font.data);\n    let cmap, glyf, loca, cff, indexToLocFormat, unitsPerEm;\n    const numTables = getUint16(data, 4);\n    for (let i = 0, p = 12; i < numTables; i++, p += 16) {\n      const tag = bytesToString(data.subarray(p, p + 4));\n      const offset = getUint32(data, p + 8);\n      const length = getUint32(data, p + 12);\n      switch (tag) {\n        case \"cmap\":\n          cmap = parseCmap(data, offset, offset + length);\n          break;\n        case \"glyf\":\n          glyf = data.subarray(offset, offset + length);\n          break;\n        case \"loca\":\n          loca = data.subarray(offset, offset + length);\n          break;\n        case \"head\":\n          unitsPerEm = getUint16(data, offset + 18);\n          indexToLocFormat = getUint16(data, offset + 50);\n          break;\n        case \"CFF \":\n          cff = parseCff(data, offset, offset + length, seacAnalysisEnabled);\n          break;\n      }\n    }\n    if (glyf) {\n      const fontMatrix = !unitsPerEm ? font.fontMatrix : [1 / unitsPerEm, 0, 0, 1 / unitsPerEm, 0, 0];\n      return new TrueTypeCompiled(parseGlyfTable(glyf, loca, indexToLocFormat), cmap, fontMatrix);\n    }\n    if (!cff) {\n      return font;\n    }\n    return new Type2Compiled(cff, cmap, font.fontMatrix, font.glyphNameMap);\n  }\n}\n\n;// ./src/core/metrics.js\n\nconst getMetrics = getLookupTableFactory(function (t) {\n  t.Courier = 600;\n  t[\"Courier-Bold\"] = 600;\n  t[\"Courier-BoldOblique\"] = 600;\n  t[\"Courier-Oblique\"] = 600;\n  t.Helvetica = getLookupTableFactory(function (t) {\n    t.space = 278;\n    t.exclam = 278;\n    t.quotedbl = 355;\n    t.numbersign = 556;\n    t.dollar = 556;\n    t.percent = 889;\n    t.ampersand = 667;\n    t.quoteright = 222;\n    t.parenleft = 333;\n    t.parenright = 333;\n    t.asterisk = 389;\n    t.plus = 584;\n    t.comma = 278;\n    t.hyphen = 333;\n    t.period = 278;\n    t.slash = 278;\n    t.zero = 556;\n    t.one = 556;\n    t.two = 556;\n    t.three = 556;\n    t.four = 556;\n    t.five = 556;\n    t.six = 556;\n    t.seven = 556;\n    t.eight = 556;\n    t.nine = 556;\n    t.colon = 278;\n    t.semicolon = 278;\n    t.less = 584;\n    t.equal = 584;\n    t.greater = 584;\n    t.question = 556;\n    t.at = 1015;\n    t.A = 667;\n    t.B = 667;\n    t.C = 722;\n    t.D = 722;\n    t.E = 667;\n    t.F = 611;\n    t.G = 778;\n    t.H = 722;\n    t.I = 278;\n    t.J = 500;\n    t.K = 667;\n    t.L = 556;\n    t.M = 833;\n    t.N = 722;\n    t.O = 778;\n    t.P = 667;\n    t.Q = 778;\n    t.R = 722;\n    t.S = 667;\n    t.T = 611;\n    t.U = 722;\n    t.V = 667;\n    t.W = 944;\n    t.X = 667;\n    t.Y = 667;\n    t.Z = 611;\n    t.bracketleft = 278;\n    t.backslash = 278;\n    t.bracketright = 278;\n    t.asciicircum = 469;\n    t.underscore = 556;\n    t.quoteleft = 222;\n    t.a = 556;\n    t.b = 556;\n    t.c = 500;\n    t.d = 556;\n    t.e = 556;\n    t.f = 278;\n    t.g = 556;\n    t.h = 556;\n    t.i = 222;\n    t.j = 222;\n    t.k = 500;\n    t.l = 222;\n    t.m = 833;\n    t.n = 556;\n    t.o = 556;\n    t.p = 556;\n    t.q = 556;\n    t.r = 333;\n    t.s = 500;\n    t.t = 278;\n    t.u = 556;\n    t.v = 500;\n    t.w = 722;\n    t.x = 500;\n    t.y = 500;\n    t.z = 500;\n    t.braceleft = 334;\n    t.bar = 260;\n    t.braceright = 334;\n    t.asciitilde = 584;\n    t.exclamdown = 333;\n    t.cent = 556;\n    t.sterling = 556;\n    t.fraction = 167;\n    t.yen = 556;\n    t.florin = 556;\n    t.section = 556;\n    t.currency = 556;\n    t.quotesingle = 191;\n    t.quotedblleft = 333;\n    t.guillemotleft = 556;\n    t.guilsinglleft = 333;\n    t.guilsinglright = 333;\n    t.fi = 500;\n    t.fl = 500;\n    t.endash = 556;\n    t.dagger = 556;\n    t.daggerdbl = 556;\n    t.periodcentered = 278;\n    t.paragraph = 537;\n    t.bullet = 350;\n    t.quotesinglbase = 222;\n    t.quotedblbase = 333;\n    t.quotedblright = 333;\n    t.guillemotright = 556;\n    t.ellipsis = 1000;\n    t.perthousand = 1000;\n    t.questiondown = 611;\n    t.grave = 333;\n    t.acute = 333;\n    t.circumflex = 333;\n    t.tilde = 333;\n    t.macron = 333;\n    t.breve = 333;\n    t.dotaccent = 333;\n    t.dieresis = 333;\n    t.ring = 333;\n    t.cedilla = 333;\n    t.hungarumlaut = 333;\n    t.ogonek = 333;\n    t.caron = 333;\n    t.emdash = 1000;\n    t.AE = 1000;\n    t.ordfeminine = 370;\n    t.Lslash = 556;\n    t.Oslash = 778;\n    t.OE = 1000;\n    t.ordmasculine = 365;\n    t.ae = 889;\n    t.dotlessi = 278;\n    t.lslash = 222;\n    t.oslash = 611;\n    t.oe = 944;\n    t.germandbls = 611;\n    t.Idieresis = 278;\n    t.eacute = 556;\n    t.abreve = 556;\n    t.uhungarumlaut = 556;\n    t.ecaron = 556;\n    t.Ydieresis = 667;\n    t.divide = 584;\n    t.Yacute = 667;\n    t.Acircumflex = 667;\n    t.aacute = 556;\n    t.Ucircumflex = 722;\n    t.yacute = 500;\n    t.scommaaccent = 500;\n    t.ecircumflex = 556;\n    t.Uring = 722;\n    t.Udieresis = 722;\n    t.aogonek = 556;\n    t.Uacute = 722;\n    t.uogonek = 556;\n    t.Edieresis = 667;\n    t.Dcroat = 722;\n    t.commaaccent = 250;\n    t.copyright = 737;\n    t.Emacron = 667;\n    t.ccaron = 500;\n    t.aring = 556;\n    t.Ncommaaccent = 722;\n    t.lacute = 222;\n    t.agrave = 556;\n    t.Tcommaaccent = 611;\n    t.Cacute = 722;\n    t.atilde = 556;\n    t.Edotaccent = 667;\n    t.scaron = 500;\n    t.scedilla = 500;\n    t.iacute = 278;\n    t.lozenge = 471;\n    t.Rcaron = 722;\n    t.Gcommaaccent = 778;\n    t.ucircumflex = 556;\n    t.acircumflex = 556;\n    t.Amacron = 667;\n    t.rcaron = 333;\n    t.ccedilla = 500;\n    t.Zdotaccent = 611;\n    t.Thorn = 667;\n    t.Omacron = 778;\n    t.Racute = 722;\n    t.Sacute = 667;\n    t.dcaron = 643;\n    t.Umacron = 722;\n    t.uring = 556;\n    t.threesuperior = 333;\n    t.Ograve = 778;\n    t.Agrave = 667;\n    t.Abreve = 667;\n    t.multiply = 584;\n    t.uacute = 556;\n    t.Tcaron = 611;\n    t.partialdiff = 476;\n    t.ydieresis = 500;\n    t.Nacute = 722;\n    t.icircumflex = 278;\n    t.Ecircumflex = 667;\n    t.adieresis = 556;\n    t.edieresis = 556;\n    t.cacute = 500;\n    t.nacute = 556;\n    t.umacron = 556;\n    t.Ncaron = 722;\n    t.Iacute = 278;\n    t.plusminus = 584;\n    t.brokenbar = 260;\n    t.registered = 737;\n    t.Gbreve = 778;\n    t.Idotaccent = 278;\n    t.summation = 600;\n    t.Egrave = 667;\n    t.racute = 333;\n    t.omacron = 556;\n    t.Zacute = 611;\n    t.Zcaron = 611;\n    t.greaterequal = 549;\n    t.Eth = 722;\n    t.Ccedilla = 722;\n    t.lcommaaccent = 222;\n    t.tcaron = 317;\n    t.eogonek = 556;\n    t.Uogonek = 722;\n    t.Aacute = 667;\n    t.Adieresis = 667;\n    t.egrave = 556;\n    t.zacute = 500;\n    t.iogonek = 222;\n    t.Oacute = 778;\n    t.oacute = 556;\n    t.amacron = 556;\n    t.sacute = 500;\n    t.idieresis = 278;\n    t.Ocircumflex = 778;\n    t.Ugrave = 722;\n    t.Delta = 612;\n    t.thorn = 556;\n    t.twosuperior = 333;\n    t.Odieresis = 778;\n    t.mu = 556;\n    t.igrave = 278;\n    t.ohungarumlaut = 556;\n    t.Eogonek = 667;\n    t.dcroat = 556;\n    t.threequarters = 834;\n    t.Scedilla = 667;\n    t.lcaron = 299;\n    t.Kcommaaccent = 667;\n    t.Lacute = 556;\n    t.trademark = 1000;\n    t.edotaccent = 556;\n    t.Igrave = 278;\n    t.Imacron = 278;\n    t.Lcaron = 556;\n    t.onehalf = 834;\n    t.lessequal = 549;\n    t.ocircumflex = 556;\n    t.ntilde = 556;\n    t.Uhungarumlaut = 722;\n    t.Eacute = 667;\n    t.emacron = 556;\n    t.gbreve = 556;\n    t.onequarter = 834;\n    t.Scaron = 667;\n    t.Scommaaccent = 667;\n    t.Ohungarumlaut = 778;\n    t.degree = 400;\n    t.ograve = 556;\n    t.Ccaron = 722;\n    t.ugrave = 556;\n    t.radical = 453;\n    t.Dcaron = 722;\n    t.rcommaaccent = 333;\n    t.Ntilde = 722;\n    t.otilde = 556;\n    t.Rcommaaccent = 722;\n    t.Lcommaaccent = 556;\n    t.Atilde = 667;\n    t.Aogonek = 667;\n    t.Aring = 667;\n    t.Otilde = 778;\n    t.zdotaccent = 500;\n    t.Ecaron = 667;\n    t.Iogonek = 278;\n    t.kcommaaccent = 500;\n    t.minus = 584;\n    t.Icircumflex = 278;\n    t.ncaron = 556;\n    t.tcommaaccent = 278;\n    t.logicalnot = 584;\n    t.odieresis = 556;\n    t.udieresis = 556;\n    t.notequal = 549;\n    t.gcommaaccent = 556;\n    t.eth = 556;\n    t.zcaron = 500;\n    t.ncommaaccent = 556;\n    t.onesuperior = 333;\n    t.imacron = 278;\n    t.Euro = 556;\n  });\n  t[\"Helvetica-Bold\"] = getLookupTableFactory(function (t) {\n    t.space = 278;\n    t.exclam = 333;\n    t.quotedbl = 474;\n    t.numbersign = 556;\n    t.dollar = 556;\n    t.percent = 889;\n    t.ampersand = 722;\n    t.quoteright = 278;\n    t.parenleft = 333;\n    t.parenright = 333;\n    t.asterisk = 389;\n    t.plus = 584;\n    t.comma = 278;\n    t.hyphen = 333;\n    t.period = 278;\n    t.slash = 278;\n    t.zero = 556;\n    t.one = 556;\n    t.two = 556;\n    t.three = 556;\n    t.four = 556;\n    t.five = 556;\n    t.six = 556;\n    t.seven = 556;\n    t.eight = 556;\n    t.nine = 556;\n    t.colon = 333;\n    t.semicolon = 333;\n    t.less = 584;\n    t.equal = 584;\n    t.greater = 584;\n    t.question = 611;\n    t.at = 975;\n    t.A = 722;\n    t.B = 722;\n    t.C = 722;\n    t.D = 722;\n    t.E = 667;\n    t.F = 611;\n    t.G = 778;\n    t.H = 722;\n    t.I = 278;\n    t.J = 556;\n    t.K = 722;\n    t.L = 611;\n    t.M = 833;\n    t.N = 722;\n    t.O = 778;\n    t.P = 667;\n    t.Q = 778;\n    t.R = 722;\n    t.S = 667;\n    t.T = 611;\n    t.U = 722;\n    t.V = 667;\n    t.W = 944;\n    t.X = 667;\n    t.Y = 667;\n    t.Z = 611;\n    t.bracketleft = 333;\n    t.backslash = 278;\n    t.bracketright = 333;\n    t.asciicircum = 584;\n    t.underscore = 556;\n    t.quoteleft = 278;\n    t.a = 556;\n    t.b = 611;\n    t.c = 556;\n    t.d = 611;\n    t.e = 556;\n    t.f = 333;\n    t.g = 611;\n    t.h = 611;\n    t.i = 278;\n    t.j = 278;\n    t.k = 556;\n    t.l = 278;\n    t.m = 889;\n    t.n = 611;\n    t.o = 611;\n    t.p = 611;\n    t.q = 611;\n    t.r = 389;\n    t.s = 556;\n    t.t = 333;\n    t.u = 611;\n    t.v = 556;\n    t.w = 778;\n    t.x = 556;\n    t.y = 556;\n    t.z = 500;\n    t.braceleft = 389;\n    t.bar = 280;\n    t.braceright = 389;\n    t.asciitilde = 584;\n    t.exclamdown = 333;\n    t.cent = 556;\n    t.sterling = 556;\n    t.fraction = 167;\n    t.yen = 556;\n    t.florin = 556;\n    t.section = 556;\n    t.currency = 556;\n    t.quotesingle = 238;\n    t.quotedblleft = 500;\n    t.guillemotleft = 556;\n    t.guilsinglleft = 333;\n    t.guilsinglright = 333;\n    t.fi = 611;\n    t.fl = 611;\n    t.endash = 556;\n    t.dagger = 556;\n    t.daggerdbl = 556;\n    t.periodcentered = 278;\n    t.paragraph = 556;\n    t.bullet = 350;\n    t.quotesinglbase = 278;\n    t.quotedblbase = 500;\n    t.quotedblright = 500;\n    t.guillemotright = 556;\n    t.ellipsis = 1000;\n    t.perthousand = 1000;\n    t.questiondown = 611;\n    t.grave = 333;\n    t.acute = 333;\n    t.circumflex = 333;\n    t.tilde = 333;\n    t.macron = 333;\n    t.breve = 333;\n    t.dotaccent = 333;\n    t.dieresis = 333;\n    t.ring = 333;\n    t.cedilla = 333;\n    t.hungarumlaut = 333;\n    t.ogonek = 333;\n    t.caron = 333;\n    t.emdash = 1000;\n    t.AE = 1000;\n    t.ordfeminine = 370;\n    t.Lslash = 611;\n    t.Oslash = 778;\n    t.OE = 1000;\n    t.ordmasculine = 365;\n    t.ae = 889;\n    t.dotlessi = 278;\n    t.lslash = 278;\n    t.oslash = 611;\n    t.oe = 944;\n    t.germandbls = 611;\n    t.Idieresis = 278;\n    t.eacute = 556;\n    t.abreve = 556;\n    t.uhungarumlaut = 611;\n    t.ecaron = 556;\n    t.Ydieresis = 667;\n    t.divide = 584;\n    t.Yacute = 667;\n    t.Acircumflex = 722;\n    t.aacute = 556;\n    t.Ucircumflex = 722;\n    t.yacute = 556;\n    t.scommaaccent = 556;\n    t.ecircumflex = 556;\n    t.Uring = 722;\n    t.Udieresis = 722;\n    t.aogonek = 556;\n    t.Uacute = 722;\n    t.uogonek = 611;\n    t.Edieresis = 667;\n    t.Dcroat = 722;\n    t.commaaccent = 250;\n    t.copyright = 737;\n    t.Emacron = 667;\n    t.ccaron = 556;\n    t.aring = 556;\n    t.Ncommaaccent = 722;\n    t.lacute = 278;\n    t.agrave = 556;\n    t.Tcommaaccent = 611;\n    t.Cacute = 722;\n    t.atilde = 556;\n    t.Edotaccent = 667;\n    t.scaron = 556;\n    t.scedilla = 556;\n    t.iacute = 278;\n    t.lozenge = 494;\n    t.Rcaron = 722;\n    t.Gcommaaccent = 778;\n    t.ucircumflex = 611;\n    t.acircumflex = 556;\n    t.Amacron = 722;\n    t.rcaron = 389;\n    t.ccedilla = 556;\n    t.Zdotaccent = 611;\n    t.Thorn = 667;\n    t.Omacron = 778;\n    t.Racute = 722;\n    t.Sacute = 667;\n    t.dcaron = 743;\n    t.Umacron = 722;\n    t.uring = 611;\n    t.threesuperior = 333;\n    t.Ograve = 778;\n    t.Agrave = 722;\n    t.Abreve = 722;\n    t.multiply = 584;\n    t.uacute = 611;\n    t.Tcaron = 611;\n    t.partialdiff = 494;\n    t.ydieresis = 556;\n    t.Nacute = 722;\n    t.icircumflex = 278;\n    t.Ecircumflex = 667;\n    t.adieresis = 556;\n    t.edieresis = 556;\n    t.cacute = 556;\n    t.nacute = 611;\n    t.umacron = 611;\n    t.Ncaron = 722;\n    t.Iacute = 278;\n    t.plusminus = 584;\n    t.brokenbar = 280;\n    t.registered = 737;\n    t.Gbreve = 778;\n    t.Idotaccent = 278;\n    t.summation = 600;\n    t.Egrave = 667;\n    t.racute = 389;\n    t.omacron = 611;\n    t.Zacute = 611;\n    t.Zcaron = 611;\n    t.greaterequal = 549;\n    t.Eth = 722;\n    t.Ccedilla = 722;\n    t.lcommaaccent = 278;\n    t.tcaron = 389;\n    t.eogonek = 556;\n    t.Uogonek = 722;\n    t.Aacute = 722;\n    t.Adieresis = 722;\n    t.egrave = 556;\n    t.zacute = 500;\n    t.iogonek = 278;\n    t.Oacute = 778;\n    t.oacute = 611;\n    t.amacron = 556;\n    t.sacute = 556;\n    t.idieresis = 278;\n    t.Ocircumflex = 778;\n    t.Ugrave = 722;\n    t.Delta = 612;\n    t.thorn = 611;\n    t.twosuperior = 333;\n    t.Odieresis = 778;\n    t.mu = 611;\n    t.igrave = 278;\n    t.ohungarumlaut = 611;\n    t.Eogonek = 667;\n    t.dcroat = 611;\n    t.threequarters = 834;\n    t.Scedilla = 667;\n    t.lcaron = 400;\n    t.Kcommaaccent = 722;\n    t.Lacute = 611;\n    t.trademark = 1000;\n    t.edotaccent = 556;\n    t.Igrave = 278;\n    t.Imacron = 278;\n    t.Lcaron = 611;\n    t.onehalf = 834;\n    t.lessequal = 549;\n    t.ocircumflex = 611;\n    t.ntilde = 611;\n    t.Uhungarumlaut = 722;\n    t.Eacute = 667;\n    t.emacron = 556;\n    t.gbreve = 611;\n    t.onequarter = 834;\n    t.Scaron = 667;\n    t.Scommaaccent = 667;\n    t.Ohungarumlaut = 778;\n    t.degree = 400;\n    t.ograve = 611;\n    t.Ccaron = 722;\n    t.ugrave = 611;\n    t.radical = 549;\n    t.Dcaron = 722;\n    t.rcommaaccent = 389;\n    t.Ntilde = 722;\n    t.otilde = 611;\n    t.Rcommaaccent = 722;\n    t.Lcommaaccent = 611;\n    t.Atilde = 722;\n    t.Aogonek = 722;\n    t.Aring = 722;\n    t.Otilde = 778;\n    t.zdotaccent = 500;\n    t.Ecaron = 667;\n    t.Iogonek = 278;\n    t.kcommaaccent = 556;\n    t.minus = 584;\n    t.Icircumflex = 278;\n    t.ncaron = 611;\n    t.tcommaaccent = 333;\n    t.logicalnot = 584;\n    t.odieresis = 611;\n    t.udieresis = 611;\n    t.notequal = 549;\n    t.gcommaaccent = 611;\n    t.eth = 611;\n    t.zcaron = 500;\n    t.ncommaaccent = 611;\n    t.onesuperior = 333;\n    t.imacron = 278;\n    t.Euro = 556;\n  });\n  t[\"Helvetica-BoldOblique\"] = getLookupTableFactory(function (t) {\n    t.space = 278;\n    t.exclam = 333;\n    t.quotedbl = 474;\n    t.numbersign = 556;\n    t.dollar = 556;\n    t.percent = 889;\n    t.ampersand = 722;\n    t.quoteright = 278;\n    t.parenleft = 333;\n    t.parenright = 333;\n    t.asterisk = 389;\n    t.plus = 584;\n    t.comma = 278;\n    t.hyphen = 333;\n    t.period = 278;\n    t.slash = 278;\n    t.zero = 556;\n    t.one = 556;\n    t.two = 556;\n    t.three = 556;\n    t.four = 556;\n    t.five = 556;\n    t.six = 556;\n    t.seven = 556;\n    t.eight = 556;\n    t.nine = 556;\n    t.colon = 333;\n    t.semicolon = 333;\n    t.less = 584;\n    t.equal = 584;\n    t.greater = 584;\n    t.question = 611;\n    t.at = 975;\n    t.A = 722;\n    t.B = 722;\n    t.C = 722;\n    t.D = 722;\n    t.E = 667;\n    t.F = 611;\n    t.G = 778;\n    t.H = 722;\n    t.I = 278;\n    t.J = 556;\n    t.K = 722;\n    t.L = 611;\n    t.M = 833;\n    t.N = 722;\n    t.O = 778;\n    t.P = 667;\n    t.Q = 778;\n    t.R = 722;\n    t.S = 667;\n    t.T = 611;\n    t.U = 722;\n    t.V = 667;\n    t.W = 944;\n    t.X = 667;\n    t.Y = 667;\n    t.Z = 611;\n    t.bracketleft = 333;\n    t.backslash = 278;\n    t.bracketright = 333;\n    t.asciicircum = 584;\n    t.underscore = 556;\n    t.quoteleft = 278;\n    t.a = 556;\n    t.b = 611;\n    t.c = 556;\n    t.d = 611;\n    t.e = 556;\n    t.f = 333;\n    t.g = 611;\n    t.h = 611;\n    t.i = 278;\n    t.j = 278;\n    t.k = 556;\n    t.l = 278;\n    t.m = 889;\n    t.n = 611;\n    t.o = 611;\n    t.p = 611;\n    t.q = 611;\n    t.r = 389;\n    t.s = 556;\n    t.t = 333;\n    t.u = 611;\n    t.v = 556;\n    t.w = 778;\n    t.x = 556;\n    t.y = 556;\n    t.z = 500;\n    t.braceleft = 389;\n    t.bar = 280;\n    t.braceright = 389;\n    t.asciitilde = 584;\n    t.exclamdown = 333;\n    t.cent = 556;\n    t.sterling = 556;\n    t.fraction = 167;\n    t.yen = 556;\n    t.florin = 556;\n    t.section = 556;\n    t.currency = 556;\n    t.quotesingle = 238;\n    t.quotedblleft = 500;\n    t.guillemotleft = 556;\n    t.guilsinglleft = 333;\n    t.guilsinglright = 333;\n    t.fi = 611;\n    t.fl = 611;\n    t.endash = 556;\n    t.dagger = 556;\n    t.daggerdbl = 556;\n    t.periodcentered = 278;\n    t.paragraph = 556;\n    t.bullet = 350;\n    t.quotesinglbase = 278;\n    t.quotedblbase = 500;\n    t.quotedblright = 500;\n    t.guillemotright = 556;\n    t.ellipsis = 1000;\n    t.perthousand = 1000;\n    t.questiondown = 611;\n    t.grave = 333;\n    t.acute = 333;\n    t.circumflex = 333;\n    t.tilde = 333;\n    t.macron = 333;\n    t.breve = 333;\n    t.dotaccent = 333;\n    t.dieresis = 333;\n    t.ring = 333;\n    t.cedilla = 333;\n    t.hungarumlaut = 333;\n    t.ogonek = 333;\n    t.caron = 333;\n    t.emdash = 1000;\n    t.AE = 1000;\n    t.ordfeminine = 370;\n    t.Lslash = 611;\n    t.Oslash = 778;\n    t.OE = 1000;\n    t.ordmasculine = 365;\n    t.ae = 889;\n    t.dotlessi = 278;\n    t.lslash = 278;\n    t.oslash = 611;\n    t.oe = 944;\n    t.germandbls = 611;\n    t.Idieresis = 278;\n    t.eacute = 556;\n    t.abreve = 556;\n    t.uhungarumlaut = 611;\n    t.ecaron = 556;\n    t.Ydieresis = 667;\n    t.divide = 584;\n    t.Yacute = 667;\n    t.Acircumflex = 722;\n    t.aacute = 556;\n    t.Ucircumflex = 722;\n    t.yacute = 556;\n    t.scommaaccent = 556;\n    t.ecircumflex = 556;\n    t.Uring = 722;\n    t.Udieresis = 722;\n    t.aogonek = 556;\n    t.Uacute = 722;\n    t.uogonek = 611;\n    t.Edieresis = 667;\n    t.Dcroat = 722;\n    t.commaaccent = 250;\n    t.copyright = 737;\n    t.Emacron = 667;\n    t.ccaron = 556;\n    t.aring = 556;\n    t.Ncommaaccent = 722;\n    t.lacute = 278;\n    t.agrave = 556;\n    t.Tcommaaccent = 611;\n    t.Cacute = 722;\n    t.atilde = 556;\n    t.Edotaccent = 667;\n    t.scaron = 556;\n    t.scedilla = 556;\n    t.iacute = 278;\n    t.lozenge = 494;\n    t.Rcaron = 722;\n    t.Gcommaaccent = 778;\n    t.ucircumflex = 611;\n    t.acircumflex = 556;\n    t.Amacron = 722;\n    t.rcaron = 389;\n    t.ccedilla = 556;\n    t.Zdotaccent = 611;\n    t.Thorn = 667;\n    t.Omacron = 778;\n    t.Racute = 722;\n    t.Sacute = 667;\n    t.dcaron = 743;\n    t.Umacron = 722;\n    t.uring = 611;\n    t.threesuperior = 333;\n    t.Ograve = 778;\n    t.Agrave = 722;\n    t.Abreve = 722;\n    t.multiply = 584;\n    t.uacute = 611;\n    t.Tcaron = 611;\n    t.partialdiff = 494;\n    t.ydieresis = 556;\n    t.Nacute = 722;\n    t.icircumflex = 278;\n    t.Ecircumflex = 667;\n    t.adieresis = 556;\n    t.edieresis = 556;\n    t.cacute = 556;\n    t.nacute = 611;\n    t.umacron = 611;\n    t.Ncaron = 722;\n    t.Iacute = 278;\n    t.plusminus = 584;\n    t.brokenbar = 280;\n    t.registered = 737;\n    t.Gbreve = 778;\n    t.Idotaccent = 278;\n    t.summation = 600;\n    t.Egrave = 667;\n    t.racute = 389;\n    t.omacron = 611;\n    t.Zacute = 611;\n    t.Zcaron = 611;\n    t.greaterequal = 549;\n    t.Eth = 722;\n    t.Ccedilla = 722;\n    t.lcommaaccent = 278;\n    t.tcaron = 389;\n    t.eogonek = 556;\n    t.Uogonek = 722;\n    t.Aacute = 722;\n    t.Adieresis = 722;\n    t.egrave = 556;\n    t.zacute = 500;\n    t.iogonek = 278;\n    t.Oacute = 778;\n    t.oacute = 611;\n    t.amacron = 556;\n    t.sacute = 556;\n    t.idieresis = 278;\n    t.Ocircumflex = 778;\n    t.Ugrave = 722;\n    t.Delta = 612;\n    t.thorn = 611;\n    t.twosuperior = 333;\n    t.Odieresis = 778;\n    t.mu = 611;\n    t.igrave = 278;\n    t.ohungarumlaut = 611;\n    t.Eogonek = 667;\n    t.dcroat = 611;\n    t.threequarters = 834;\n    t.Scedilla = 667;\n    t.lcaron = 400;\n    t.Kcommaaccent = 722;\n    t.Lacute = 611;\n    t.trademark = 1000;\n    t.edotaccent = 556;\n    t.Igrave = 278;\n    t.Imacron = 278;\n    t.Lcaron = 611;\n    t.onehalf = 834;\n    t.lessequal = 549;\n    t.ocircumflex = 611;\n    t.ntilde = 611;\n    t.Uhungarumlaut = 722;\n    t.Eacute = 667;\n    t.emacron = 556;\n    t.gbreve = 611;\n    t.onequarter = 834;\n    t.Scaron = 667;\n    t.Scommaaccent = 667;\n    t.Ohungarumlaut = 778;\n    t.degree = 400;\n    t.ograve = 611;\n    t.Ccaron = 722;\n    t.ugrave = 611;\n    t.radical = 549;\n    t.Dcaron = 722;\n    t.rcommaaccent = 389;\n    t.Ntilde = 722;\n    t.otilde = 611;\n    t.Rcommaaccent = 722;\n    t.Lcommaaccent = 611;\n    t.Atilde = 722;\n    t.Aogonek = 722;\n    t.Aring = 722;\n    t.Otilde = 778;\n    t.zdotaccent = 500;\n    t.Ecaron = 667;\n    t.Iogonek = 278;\n    t.kcommaaccent = 556;\n    t.minus = 584;\n    t.Icircumflex = 278;\n    t.ncaron = 611;\n    t.tcommaaccent = 333;\n    t.logicalnot = 584;\n    t.odieresis = 611;\n    t.udieresis = 611;\n    t.notequal = 549;\n    t.gcommaaccent = 611;\n    t.eth = 611;\n    t.zcaron = 500;\n    t.ncommaaccent = 611;\n    t.onesuperior = 333;\n    t.imacron = 278;\n    t.Euro = 556;\n  });\n  t[\"Helvetica-Oblique\"] = getLookupTableFactory(function (t) {\n    t.space = 278;\n    t.exclam = 278;\n    t.quotedbl = 355;\n    t.numbersign = 556;\n    t.dollar = 556;\n    t.percent = 889;\n    t.ampersand = 667;\n    t.quoteright = 222;\n    t.parenleft = 333;\n    t.parenright = 333;\n    t.asterisk = 389;\n    t.plus = 584;\n    t.comma = 278;\n    t.hyphen = 333;\n    t.period = 278;\n    t.slash = 278;\n    t.zero = 556;\n    t.one = 556;\n    t.two = 556;\n    t.three = 556;\n    t.four = 556;\n    t.five = 556;\n    t.six = 556;\n    t.seven = 556;\n    t.eight = 556;\n    t.nine = 556;\n    t.colon = 278;\n    t.semicolon = 278;\n    t.less = 584;\n    t.equal = 584;\n    t.greater = 584;\n    t.question = 556;\n    t.at = 1015;\n    t.A = 667;\n    t.B = 667;\n    t.C = 722;\n    t.D = 722;\n    t.E = 667;\n    t.F = 611;\n    t.G = 778;\n    t.H = 722;\n    t.I = 278;\n    t.J = 500;\n    t.K = 667;\n    t.L = 556;\n    t.M = 833;\n    t.N = 722;\n    t.O = 778;\n    t.P = 667;\n    t.Q = 778;\n    t.R = 722;\n    t.S = 667;\n    t.T = 611;\n    t.U = 722;\n    t.V = 667;\n    t.W = 944;\n    t.X = 667;\n    t.Y = 667;\n    t.Z = 611;\n    t.bracketleft = 278;\n    t.backslash = 278;\n    t.bracketright = 278;\n    t.asciicircum = 469;\n    t.underscore = 556;\n    t.quoteleft = 222;\n    t.a = 556;\n    t.b = 556;\n    t.c = 500;\n    t.d = 556;\n    t.e = 556;\n    t.f = 278;\n    t.g = 556;\n    t.h = 556;\n    t.i = 222;\n    t.j = 222;\n    t.k = 500;\n    t.l = 222;\n    t.m = 833;\n    t.n = 556;\n    t.o = 556;\n    t.p = 556;\n    t.q = 556;\n    t.r = 333;\n    t.s = 500;\n    t.t = 278;\n    t.u = 556;\n    t.v = 500;\n    t.w = 722;\n    t.x = 500;\n    t.y = 500;\n    t.z = 500;\n    t.braceleft = 334;\n    t.bar = 260;\n    t.braceright = 334;\n    t.asciitilde = 584;\n    t.exclamdown = 333;\n    t.cent = 556;\n    t.sterling = 556;\n    t.fraction = 167;\n    t.yen = 556;\n    t.florin = 556;\n    t.section = 556;\n    t.currency = 556;\n    t.quotesingle = 191;\n    t.quotedblleft = 333;\n    t.guillemotleft = 556;\n    t.guilsinglleft = 333;\n    t.guilsinglright = 333;\n    t.fi = 500;\n    t.fl = 500;\n    t.endash = 556;\n    t.dagger = 556;\n    t.daggerdbl = 556;\n    t.periodcentered = 278;\n    t.paragraph = 537;\n    t.bullet = 350;\n    t.quotesinglbase = 222;\n    t.quotedblbase = 333;\n    t.quotedblright = 333;\n    t.guillemotright = 556;\n    t.ellipsis = 1000;\n    t.perthousand = 1000;\n    t.questiondown = 611;\n    t.grave = 333;\n    t.acute = 333;\n    t.circumflex = 333;\n    t.tilde = 333;\n    t.macron = 333;\n    t.breve = 333;\n    t.dotaccent = 333;\n    t.dieresis = 333;\n    t.ring = 333;\n    t.cedilla = 333;\n    t.hungarumlaut = 333;\n    t.ogonek = 333;\n    t.caron = 333;\n    t.emdash = 1000;\n    t.AE = 1000;\n    t.ordfeminine = 370;\n    t.Lslash = 556;\n    t.Oslash = 778;\n    t.OE = 1000;\n    t.ordmasculine = 365;\n    t.ae = 889;\n    t.dotlessi = 278;\n    t.lslash = 222;\n    t.oslash = 611;\n    t.oe = 944;\n    t.germandbls = 611;\n    t.Idieresis = 278;\n    t.eacute = 556;\n    t.abreve = 556;\n    t.uhungarumlaut = 556;\n    t.ecaron = 556;\n    t.Ydieresis = 667;\n    t.divide = 584;\n    t.Yacute = 667;\n    t.Acircumflex = 667;\n    t.aacute = 556;\n    t.Ucircumflex = 722;\n    t.yacute = 500;\n    t.scommaaccent = 500;\n    t.ecircumflex = 556;\n    t.Uring = 722;\n    t.Udieresis = 722;\n    t.aogonek = 556;\n    t.Uacute = 722;\n    t.uogonek = 556;\n    t.Edieresis = 667;\n    t.Dcroat = 722;\n    t.commaaccent = 250;\n    t.copyright = 737;\n    t.Emacron = 667;\n    t.ccaron = 500;\n    t.aring = 556;\n    t.Ncommaaccent = 722;\n    t.lacute = 222;\n    t.agrave = 556;\n    t.Tcommaaccent = 611;\n    t.Cacute = 722;\n    t.atilde = 556;\n    t.Edotaccent = 667;\n    t.scaron = 500;\n    t.scedilla = 500;\n    t.iacute = 278;\n    t.lozenge = 471;\n    t.Rcaron = 722;\n    t.Gcommaaccent = 778;\n    t.ucircumflex = 556;\n    t.acircumflex = 556;\n    t.Amacron = 667;\n    t.rcaron = 333;\n    t.ccedilla = 500;\n    t.Zdotaccent = 611;\n    t.Thorn = 667;\n    t.Omacron = 778;\n    t.Racute = 722;\n    t.Sacute = 667;\n    t.dcaron = 643;\n    t.Umacron = 722;\n    t.uring = 556;\n    t.threesuperior = 333;\n    t.Ograve = 778;\n    t.Agrave = 667;\n    t.Abreve = 667;\n    t.multiply = 584;\n    t.uacute = 556;\n    t.Tcaron = 611;\n    t.partialdiff = 476;\n    t.ydieresis = 500;\n    t.Nacute = 722;\n    t.icircumflex = 278;\n    t.Ecircumflex = 667;\n    t.adieresis = 556;\n    t.edieresis = 556;\n    t.cacute = 500;\n    t.nacute = 556;\n    t.umacron = 556;\n    t.Ncaron = 722;\n    t.Iacute = 278;\n    t.plusminus = 584;\n    t.brokenbar = 260;\n    t.registered = 737;\n    t.Gbreve = 778;\n    t.Idotaccent = 278;\n    t.summation = 600;\n    t.Egrave = 667;\n    t.racute = 333;\n    t.omacron = 556;\n    t.Zacute = 611;\n    t.Zcaron = 611;\n    t.greaterequal = 549;\n    t.Eth = 722;\n    t.Ccedilla = 722;\n    t.lcommaaccent = 222;\n    t.tcaron = 317;\n    t.eogonek = 556;\n    t.Uogonek = 722;\n    t.Aacute = 667;\n    t.Adieresis = 667;\n    t.egrave = 556;\n    t.zacute = 500;\n    t.iogonek = 222;\n    t.Oacute = 778;\n    t.oacute = 556;\n    t.amacron = 556;\n    t.sacute = 500;\n    t.idieresis = 278;\n    t.Ocircumflex = 778;\n    t.Ugrave = 722;\n    t.Delta = 612;\n    t.thorn = 556;\n    t.twosuperior = 333;\n    t.Odieresis = 778;\n    t.mu = 556;\n    t.igrave = 278;\n    t.ohungarumlaut = 556;\n    t.Eogonek = 667;\n    t.dcroat = 556;\n    t.threequarters = 834;\n    t.Scedilla = 667;\n    t.lcaron = 299;\n    t.Kcommaaccent = 667;\n    t.Lacute = 556;\n    t.trademark = 1000;\n    t.edotaccent = 556;\n    t.Igrave = 278;\n    t.Imacron = 278;\n    t.Lcaron = 556;\n    t.onehalf = 834;\n    t.lessequal = 549;\n    t.ocircumflex = 556;\n    t.ntilde = 556;\n    t.Uhungarumlaut = 722;\n    t.Eacute = 667;\n    t.emacron = 556;\n    t.gbreve = 556;\n    t.onequarter = 834;\n    t.Scaron = 667;\n    t.Scommaaccent = 667;\n    t.Ohungarumlaut = 778;\n    t.degree = 400;\n    t.ograve = 556;\n    t.Ccaron = 722;\n    t.ugrave = 556;\n    t.radical = 453;\n    t.Dcaron = 722;\n    t.rcommaaccent = 333;\n    t.Ntilde = 722;\n    t.otilde = 556;\n    t.Rcommaaccent = 722;\n    t.Lcommaaccent = 556;\n    t.Atilde = 667;\n    t.Aogonek = 667;\n    t.Aring = 667;\n    t.Otilde = 778;\n    t.zdotaccent = 500;\n    t.Ecaron = 667;\n    t.Iogonek = 278;\n    t.kcommaaccent = 500;\n    t.minus = 584;\n    t.Icircumflex = 278;\n    t.ncaron = 556;\n    t.tcommaaccent = 278;\n    t.logicalnot = 584;\n    t.odieresis = 556;\n    t.udieresis = 556;\n    t.notequal = 549;\n    t.gcommaaccent = 556;\n    t.eth = 556;\n    t.zcaron = 500;\n    t.ncommaaccent = 556;\n    t.onesuperior = 333;\n    t.imacron = 278;\n    t.Euro = 556;\n  });\n  t.Symbol = getLookupTableFactory(function (t) {\n    t.space = 250;\n    t.exclam = 333;\n    t.universal = 713;\n    t.numbersign = 500;\n    t.existential = 549;\n    t.percent = 833;\n    t.ampersand = 778;\n    t.suchthat = 439;\n    t.parenleft = 333;\n    t.parenright = 333;\n    t.asteriskmath = 500;\n    t.plus = 549;\n    t.comma = 250;\n    t.minus = 549;\n    t.period = 250;\n    t.slash = 278;\n    t.zero = 500;\n    t.one = 500;\n    t.two = 500;\n    t.three = 500;\n    t.four = 500;\n    t.five = 500;\n    t.six = 500;\n    t.seven = 500;\n    t.eight = 500;\n    t.nine = 500;\n    t.colon = 278;\n    t.semicolon = 278;\n    t.less = 549;\n    t.equal = 549;\n    t.greater = 549;\n    t.question = 444;\n    t.congruent = 549;\n    t.Alpha = 722;\n    t.Beta = 667;\n    t.Chi = 722;\n    t.Delta = 612;\n    t.Epsilon = 611;\n    t.Phi = 763;\n    t.Gamma = 603;\n    t.Eta = 722;\n    t.Iota = 333;\n    t.theta1 = 631;\n    t.Kappa = 722;\n    t.Lambda = 686;\n    t.Mu = 889;\n    t.Nu = 722;\n    t.Omicron = 722;\n    t.Pi = 768;\n    t.Theta = 741;\n    t.Rho = 556;\n    t.Sigma = 592;\n    t.Tau = 611;\n    t.Upsilon = 690;\n    t.sigma1 = 439;\n    t.Omega = 768;\n    t.Xi = 645;\n    t.Psi = 795;\n    t.Zeta = 611;\n    t.bracketleft = 333;\n    t.therefore = 863;\n    t.bracketright = 333;\n    t.perpendicular = 658;\n    t.underscore = 500;\n    t.radicalex = 500;\n    t.alpha = 631;\n    t.beta = 549;\n    t.chi = 549;\n    t.delta = 494;\n    t.epsilon = 439;\n    t.phi = 521;\n    t.gamma = 411;\n    t.eta = 603;\n    t.iota = 329;\n    t.phi1 = 603;\n    t.kappa = 549;\n    t.lambda = 549;\n    t.mu = 576;\n    t.nu = 521;\n    t.omicron = 549;\n    t.pi = 549;\n    t.theta = 521;\n    t.rho = 549;\n    t.sigma = 603;\n    t.tau = 439;\n    t.upsilon = 576;\n    t.omega1 = 713;\n    t.omega = 686;\n    t.xi = 493;\n    t.psi = 686;\n    t.zeta = 494;\n    t.braceleft = 480;\n    t.bar = 200;\n    t.braceright = 480;\n    t.similar = 549;\n    t.Euro = 750;\n    t.Upsilon1 = 620;\n    t.minute = 247;\n    t.lessequal = 549;\n    t.fraction = 167;\n    t.infinity = 713;\n    t.florin = 500;\n    t.club = 753;\n    t.diamond = 753;\n    t.heart = 753;\n    t.spade = 753;\n    t.arrowboth = 1042;\n    t.arrowleft = 987;\n    t.arrowup = 603;\n    t.arrowright = 987;\n    t.arrowdown = 603;\n    t.degree = 400;\n    t.plusminus = 549;\n    t.second = 411;\n    t.greaterequal = 549;\n    t.multiply = 549;\n    t.proportional = 713;\n    t.partialdiff = 494;\n    t.bullet = 460;\n    t.divide = 549;\n    t.notequal = 549;\n    t.equivalence = 549;\n    t.approxequal = 549;\n    t.ellipsis = 1000;\n    t.arrowvertex = 603;\n    t.arrowhorizex = 1000;\n    t.carriagereturn = 658;\n    t.aleph = 823;\n    t.Ifraktur = 686;\n    t.Rfraktur = 795;\n    t.weierstrass = 987;\n    t.circlemultiply = 768;\n    t.circleplus = 768;\n    t.emptyset = 823;\n    t.intersection = 768;\n    t.union = 768;\n    t.propersuperset = 713;\n    t.reflexsuperset = 713;\n    t.notsubset = 713;\n    t.propersubset = 713;\n    t.reflexsubset = 713;\n    t.element = 713;\n    t.notelement = 713;\n    t.angle = 768;\n    t.gradient = 713;\n    t.registerserif = 790;\n    t.copyrightserif = 790;\n    t.trademarkserif = 890;\n    t.product = 823;\n    t.radical = 549;\n    t.dotmath = 250;\n    t.logicalnot = 713;\n    t.logicaland = 603;\n    t.logicalor = 603;\n    t.arrowdblboth = 1042;\n    t.arrowdblleft = 987;\n    t.arrowdblup = 603;\n    t.arrowdblright = 987;\n    t.arrowdbldown = 603;\n    t.lozenge = 494;\n    t.angleleft = 329;\n    t.registersans = 790;\n    t.copyrightsans = 790;\n    t.trademarksans = 786;\n    t.summation = 713;\n    t.parenlefttp = 384;\n    t.parenleftex = 384;\n    t.parenleftbt = 384;\n    t.bracketlefttp = 384;\n    t.bracketleftex = 384;\n    t.bracketleftbt = 384;\n    t.bracelefttp = 494;\n    t.braceleftmid = 494;\n    t.braceleftbt = 494;\n    t.braceex = 494;\n    t.angleright = 329;\n    t.integral = 274;\n    t.integraltp = 686;\n    t.integralex = 686;\n    t.integralbt = 686;\n    t.parenrighttp = 384;\n    t.parenrightex = 384;\n    t.parenrightbt = 384;\n    t.bracketrighttp = 384;\n    t.bracketrightex = 384;\n    t.bracketrightbt = 384;\n    t.bracerighttp = 494;\n    t.bracerightmid = 494;\n    t.bracerightbt = 494;\n    t.apple = 790;\n  });\n  t[\"Times-Roman\"] = getLookupTableFactory(function (t) {\n    t.space = 250;\n    t.exclam = 333;\n    t.quotedbl = 408;\n    t.numbersign = 500;\n    t.dollar = 500;\n    t.percent = 833;\n    t.ampersand = 778;\n    t.quoteright = 333;\n    t.parenleft = 333;\n    t.parenright = 333;\n    t.asterisk = 500;\n    t.plus = 564;\n    t.comma = 250;\n    t.hyphen = 333;\n    t.period = 250;\n    t.slash = 278;\n    t.zero = 500;\n    t.one = 500;\n    t.two = 500;\n    t.three = 500;\n    t.four = 500;\n    t.five = 500;\n    t.six = 500;\n    t.seven = 500;\n    t.eight = 500;\n    t.nine = 500;\n    t.colon = 278;\n    t.semicolon = 278;\n    t.less = 564;\n    t.equal = 564;\n    t.greater = 564;\n    t.question = 444;\n    t.at = 921;\n    t.A = 722;\n    t.B = 667;\n    t.C = 667;\n    t.D = 722;\n    t.E = 611;\n    t.F = 556;\n    t.G = 722;\n    t.H = 722;\n    t.I = 333;\n    t.J = 389;\n    t.K = 722;\n    t.L = 611;\n    t.M = 889;\n    t.N = 722;\n    t.O = 722;\n    t.P = 556;\n    t.Q = 722;\n    t.R = 667;\n    t.S = 556;\n    t.T = 611;\n    t.U = 722;\n    t.V = 722;\n    t.W = 944;\n    t.X = 722;\n    t.Y = 722;\n    t.Z = 611;\n    t.bracketleft = 333;\n    t.backslash = 278;\n    t.bracketright = 333;\n    t.asciicircum = 469;\n    t.underscore = 500;\n    t.quoteleft = 333;\n    t.a = 444;\n    t.b = 500;\n    t.c = 444;\n    t.d = 500;\n    t.e = 444;\n    t.f = 333;\n    t.g = 500;\n    t.h = 500;\n    t.i = 278;\n    t.j = 278;\n    t.k = 500;\n    t.l = 278;\n    t.m = 778;\n    t.n = 500;\n    t.o = 500;\n    t.p = 500;\n    t.q = 500;\n    t.r = 333;\n    t.s = 389;\n    t.t = 278;\n    t.u = 500;\n    t.v = 500;\n    t.w = 722;\n    t.x = 500;\n    t.y = 500;\n    t.z = 444;\n    t.braceleft = 480;\n    t.bar = 200;\n    t.braceright = 480;\n    t.asciitilde = 541;\n    t.exclamdown = 333;\n    t.cent = 500;\n    t.sterling = 500;\n    t.fraction = 167;\n    t.yen = 500;\n    t.florin = 500;\n    t.section = 500;\n    t.currency = 500;\n    t.quotesingle = 180;\n    t.quotedblleft = 444;\n    t.guillemotleft = 500;\n    t.guilsinglleft = 333;\n    t.guilsinglright = 333;\n    t.fi = 556;\n    t.fl = 556;\n    t.endash = 500;\n    t.dagger = 500;\n    t.daggerdbl = 500;\n    t.periodcentered = 250;\n    t.paragraph = 453;\n    t.bullet = 350;\n    t.quotesinglbase = 333;\n    t.quotedblbase = 444;\n    t.quotedblright = 444;\n    t.guillemotright = 500;\n    t.ellipsis = 1000;\n    t.perthousand = 1000;\n    t.questiondown = 444;\n    t.grave = 333;\n    t.acute = 333;\n    t.circumflex = 333;\n    t.tilde = 333;\n    t.macron = 333;\n    t.breve = 333;\n    t.dotaccent = 333;\n    t.dieresis = 333;\n    t.ring = 333;\n    t.cedilla = 333;\n    t.hungarumlaut = 333;\n    t.ogonek = 333;\n    t.caron = 333;\n    t.emdash = 1000;\n    t.AE = 889;\n    t.ordfeminine = 276;\n    t.Lslash = 611;\n    t.Oslash = 722;\n    t.OE = 889;\n    t.ordmasculine = 310;\n    t.ae = 667;\n    t.dotlessi = 278;\n    t.lslash = 278;\n    t.oslash = 500;\n    t.oe = 722;\n    t.germandbls = 500;\n    t.Idieresis = 333;\n    t.eacute = 444;\n    t.abreve = 444;\n    t.uhungarumlaut = 500;\n    t.ecaron = 444;\n    t.Ydieresis = 722;\n    t.divide = 564;\n    t.Yacute = 722;\n    t.Acircumflex = 722;\n    t.aacute = 444;\n    t.Ucircumflex = 722;\n    t.yacute = 500;\n    t.scommaaccent = 389;\n    t.ecircumflex = 444;\n    t.Uring = 722;\n    t.Udieresis = 722;\n    t.aogonek = 444;\n    t.Uacute = 722;\n    t.uogonek = 500;\n    t.Edieresis = 611;\n    t.Dcroat = 722;\n    t.commaaccent = 250;\n    t.copyright = 760;\n    t.Emacron = 611;\n    t.ccaron = 444;\n    t.aring = 444;\n    t.Ncommaaccent = 722;\n    t.lacute = 278;\n    t.agrave = 444;\n    t.Tcommaaccent = 611;\n    t.Cacute = 667;\n    t.atilde = 444;\n    t.Edotaccent = 611;\n    t.scaron = 389;\n    t.scedilla = 389;\n    t.iacute = 278;\n    t.lozenge = 471;\n    t.Rcaron = 667;\n    t.Gcommaaccent = 722;\n    t.ucircumflex = 500;\n    t.acircumflex = 444;\n    t.Amacron = 722;\n    t.rcaron = 333;\n    t.ccedilla = 444;\n    t.Zdotaccent = 611;\n    t.Thorn = 556;\n    t.Omacron = 722;\n    t.Racute = 667;\n    t.Sacute = 556;\n    t.dcaron = 588;\n    t.Umacron = 722;\n    t.uring = 500;\n    t.threesuperior = 300;\n    t.Ograve = 722;\n    t.Agrave = 722;\n    t.Abreve = 722;\n    t.multiply = 564;\n    t.uacute = 500;\n    t.Tcaron = 611;\n    t.partialdiff = 476;\n    t.ydieresis = 500;\n    t.Nacute = 722;\n    t.icircumflex = 278;\n    t.Ecircumflex = 611;\n    t.adieresis = 444;\n    t.edieresis = 444;\n    t.cacute = 444;\n    t.nacute = 500;\n    t.umacron = 500;\n    t.Ncaron = 722;\n    t.Iacute = 333;\n    t.plusminus = 564;\n    t.brokenbar = 200;\n    t.registered = 760;\n    t.Gbreve = 722;\n    t.Idotaccent = 333;\n    t.summation = 600;\n    t.Egrave = 611;\n    t.racute = 333;\n    t.omacron = 500;\n    t.Zacute = 611;\n    t.Zcaron = 611;\n    t.greaterequal = 549;\n    t.Eth = 722;\n    t.Ccedilla = 667;\n    t.lcommaaccent = 278;\n    t.tcaron = 326;\n    t.eogonek = 444;\n    t.Uogonek = 722;\n    t.Aacute = 722;\n    t.Adieresis = 722;\n    t.egrave = 444;\n    t.zacute = 444;\n    t.iogonek = 278;\n    t.Oacute = 722;\n    t.oacute = 500;\n    t.amacron = 444;\n    t.sacute = 389;\n    t.idieresis = 278;\n    t.Ocircumflex = 722;\n    t.Ugrave = 722;\n    t.Delta = 612;\n    t.thorn = 500;\n    t.twosuperior = 300;\n    t.Odieresis = 722;\n    t.mu = 500;\n    t.igrave = 278;\n    t.ohungarumlaut = 500;\n    t.Eogonek = 611;\n    t.dcroat = 500;\n    t.threequarters = 750;\n    t.Scedilla = 556;\n    t.lcaron = 344;\n    t.Kcommaaccent = 722;\n    t.Lacute = 611;\n    t.trademark = 980;\n    t.edotaccent = 444;\n    t.Igrave = 333;\n    t.Imacron = 333;\n    t.Lcaron = 611;\n    t.onehalf = 750;\n    t.lessequal = 549;\n    t.ocircumflex = 500;\n    t.ntilde = 500;\n    t.Uhungarumlaut = 722;\n    t.Eacute = 611;\n    t.emacron = 444;\n    t.gbreve = 500;\n    t.onequarter = 750;\n    t.Scaron = 556;\n    t.Scommaaccent = 556;\n    t.Ohungarumlaut = 722;\n    t.degree = 400;\n    t.ograve = 500;\n    t.Ccaron = 667;\n    t.ugrave = 500;\n    t.radical = 453;\n    t.Dcaron = 722;\n    t.rcommaaccent = 333;\n    t.Ntilde = 722;\n    t.otilde = 500;\n    t.Rcommaaccent = 667;\n    t.Lcommaaccent = 611;\n    t.Atilde = 722;\n    t.Aogonek = 722;\n    t.Aring = 722;\n    t.Otilde = 722;\n    t.zdotaccent = 444;\n    t.Ecaron = 611;\n    t.Iogonek = 333;\n    t.kcommaaccent = 500;\n    t.minus = 564;\n    t.Icircumflex = 333;\n    t.ncaron = 500;\n    t.tcommaaccent = 278;\n    t.logicalnot = 564;\n    t.odieresis = 500;\n    t.udieresis = 500;\n    t.notequal = 549;\n    t.gcommaaccent = 500;\n    t.eth = 500;\n    t.zcaron = 444;\n    t.ncommaaccent = 500;\n    t.onesuperior = 300;\n    t.imacron = 278;\n    t.Euro = 500;\n  });\n  t[\"Times-Bold\"] = getLookupTableFactory(function (t) {\n    t.space = 250;\n    t.exclam = 333;\n    t.quotedbl = 555;\n    t.numbersign = 500;\n    t.dollar = 500;\n    t.percent = 1000;\n    t.ampersand = 833;\n    t.quoteright = 333;\n    t.parenleft = 333;\n    t.parenright = 333;\n    t.asterisk = 500;\n    t.plus = 570;\n    t.comma = 250;\n    t.hyphen = 333;\n    t.period = 250;\n    t.slash = 278;\n    t.zero = 500;\n    t.one = 500;\n    t.two = 500;\n    t.three = 500;\n    t.four = 500;\n    t.five = 500;\n    t.six = 500;\n    t.seven = 500;\n    t.eight = 500;\n    t.nine = 500;\n    t.colon = 333;\n    t.semicolon = 333;\n    t.less = 570;\n    t.equal = 570;\n    t.greater = 570;\n    t.question = 500;\n    t.at = 930;\n    t.A = 722;\n    t.B = 667;\n    t.C = 722;\n    t.D = 722;\n    t.E = 667;\n    t.F = 611;\n    t.G = 778;\n    t.H = 778;\n    t.I = 389;\n    t.J = 500;\n    t.K = 778;\n    t.L = 667;\n    t.M = 944;\n    t.N = 722;\n    t.O = 778;\n    t.P = 611;\n    t.Q = 778;\n    t.R = 722;\n    t.S = 556;\n    t.T = 667;\n    t.U = 722;\n    t.V = 722;\n    t.W = 1000;\n    t.X = 722;\n    t.Y = 722;\n    t.Z = 667;\n    t.bracketleft = 333;\n    t.backslash = 278;\n    t.bracketright = 333;\n    t.asciicircum = 581;\n    t.underscore = 500;\n    t.quoteleft = 333;\n    t.a = 500;\n    t.b = 556;\n    t.c = 444;\n    t.d = 556;\n    t.e = 444;\n    t.f = 333;\n    t.g = 500;\n    t.h = 556;\n    t.i = 278;\n    t.j = 333;\n    t.k = 556;\n    t.l = 278;\n    t.m = 833;\n    t.n = 556;\n    t.o = 500;\n    t.p = 556;\n    t.q = 556;\n    t.r = 444;\n    t.s = 389;\n    t.t = 333;\n    t.u = 556;\n    t.v = 500;\n    t.w = 722;\n    t.x = 500;\n    t.y = 500;\n    t.z = 444;\n    t.braceleft = 394;\n    t.bar = 220;\n    t.braceright = 394;\n    t.asciitilde = 520;\n    t.exclamdown = 333;\n    t.cent = 500;\n    t.sterling = 500;\n    t.fraction = 167;\n    t.yen = 500;\n    t.florin = 500;\n    t.section = 500;\n    t.currency = 500;\n    t.quotesingle = 278;\n    t.quotedblleft = 500;\n    t.guillemotleft = 500;\n    t.guilsinglleft = 333;\n    t.guilsinglright = 333;\n    t.fi = 556;\n    t.fl = 556;\n    t.endash = 500;\n    t.dagger = 500;\n    t.daggerdbl = 500;\n    t.periodcentered = 250;\n    t.paragraph = 540;\n    t.bullet = 350;\n    t.quotesinglbase = 333;\n    t.quotedblbase = 500;\n    t.quotedblright = 500;\n    t.guillemotright = 500;\n    t.ellipsis = 1000;\n    t.perthousand = 1000;\n    t.questiondown = 500;\n    t.grave = 333;\n    t.acute = 333;\n    t.circumflex = 333;\n    t.tilde = 333;\n    t.macron = 333;\n    t.breve = 333;\n    t.dotaccent = 333;\n    t.dieresis = 333;\n    t.ring = 333;\n    t.cedilla = 333;\n    t.hungarumlaut = 333;\n    t.ogonek = 333;\n    t.caron = 333;\n    t.emdash = 1000;\n    t.AE = 1000;\n    t.ordfeminine = 300;\n    t.Lslash = 667;\n    t.Oslash = 778;\n    t.OE = 1000;\n    t.ordmasculine = 330;\n    t.ae = 722;\n    t.dotlessi = 278;\n    t.lslash = 278;\n    t.oslash = 500;\n    t.oe = 722;\n    t.germandbls = 556;\n    t.Idieresis = 389;\n    t.eacute = 444;\n    t.abreve = 500;\n    t.uhungarumlaut = 556;\n    t.ecaron = 444;\n    t.Ydieresis = 722;\n    t.divide = 570;\n    t.Yacute = 722;\n    t.Acircumflex = 722;\n    t.aacute = 500;\n    t.Ucircumflex = 722;\n    t.yacute = 500;\n    t.scommaaccent = 389;\n    t.ecircumflex = 444;\n    t.Uring = 722;\n    t.Udieresis = 722;\n    t.aogonek = 500;\n    t.Uacute = 722;\n    t.uogonek = 556;\n    t.Edieresis = 667;\n    t.Dcroat = 722;\n    t.commaaccent = 250;\n    t.copyright = 747;\n    t.Emacron = 667;\n    t.ccaron = 444;\n    t.aring = 500;\n    t.Ncommaaccent = 722;\n    t.lacute = 278;\n    t.agrave = 500;\n    t.Tcommaaccent = 667;\n    t.Cacute = 722;\n    t.atilde = 500;\n    t.Edotaccent = 667;\n    t.scaron = 389;\n    t.scedilla = 389;\n    t.iacute = 278;\n    t.lozenge = 494;\n    t.Rcaron = 722;\n    t.Gcommaaccent = 778;\n    t.ucircumflex = 556;\n    t.acircumflex = 500;\n    t.Amacron = 722;\n    t.rcaron = 444;\n    t.ccedilla = 444;\n    t.Zdotaccent = 667;\n    t.Thorn = 611;\n    t.Omacron = 778;\n    t.Racute = 722;\n    t.Sacute = 556;\n    t.dcaron = 672;\n    t.Umacron = 722;\n    t.uring = 556;\n    t.threesuperior = 300;\n    t.Ograve = 778;\n    t.Agrave = 722;\n    t.Abreve = 722;\n    t.multiply = 570;\n    t.uacute = 556;\n    t.Tcaron = 667;\n    t.partialdiff = 494;\n    t.ydieresis = 500;\n    t.Nacute = 722;\n    t.icircumflex = 278;\n    t.Ecircumflex = 667;\n    t.adieresis = 500;\n    t.edieresis = 444;\n    t.cacute = 444;\n    t.nacute = 556;\n    t.umacron = 556;\n    t.Ncaron = 722;\n    t.Iacute = 389;\n    t.plusminus = 570;\n    t.brokenbar = 220;\n    t.registered = 747;\n    t.Gbreve = 778;\n    t.Idotaccent = 389;\n    t.summation = 600;\n    t.Egrave = 667;\n    t.racute = 444;\n    t.omacron = 500;\n    t.Zacute = 667;\n    t.Zcaron = 667;\n    t.greaterequal = 549;\n    t.Eth = 722;\n    t.Ccedilla = 722;\n    t.lcommaaccent = 278;\n    t.tcaron = 416;\n    t.eogonek = 444;\n    t.Uogonek = 722;\n    t.Aacute = 722;\n    t.Adieresis = 722;\n    t.egrave = 444;\n    t.zacute = 444;\n    t.iogonek = 278;\n    t.Oacute = 778;\n    t.oacute = 500;\n    t.amacron = 500;\n    t.sacute = 389;\n    t.idieresis = 278;\n    t.Ocircumflex = 778;\n    t.Ugrave = 722;\n    t.Delta = 612;\n    t.thorn = 556;\n    t.twosuperior = 300;\n    t.Odieresis = 778;\n    t.mu = 556;\n    t.igrave = 278;\n    t.ohungarumlaut = 500;\n    t.Eogonek = 667;\n    t.dcroat = 556;\n    t.threequarters = 750;\n    t.Scedilla = 556;\n    t.lcaron = 394;\n    t.Kcommaaccent = 778;\n    t.Lacute = 667;\n    t.trademark = 1000;\n    t.edotaccent = 444;\n    t.Igrave = 389;\n    t.Imacron = 389;\n    t.Lcaron = 667;\n    t.onehalf = 750;\n    t.lessequal = 549;\n    t.ocircumflex = 500;\n    t.ntilde = 556;\n    t.Uhungarumlaut = 722;\n    t.Eacute = 667;\n    t.emacron = 444;\n    t.gbreve = 500;\n    t.onequarter = 750;\n    t.Scaron = 556;\n    t.Scommaaccent = 556;\n    t.Ohungarumlaut = 778;\n    t.degree = 400;\n    t.ograve = 500;\n    t.Ccaron = 722;\n    t.ugrave = 556;\n    t.radical = 549;\n    t.Dcaron = 722;\n    t.rcommaaccent = 444;\n    t.Ntilde = 722;\n    t.otilde = 500;\n    t.Rcommaaccent = 722;\n    t.Lcommaaccent = 667;\n    t.Atilde = 722;\n    t.Aogonek = 722;\n    t.Aring = 722;\n    t.Otilde = 778;\n    t.zdotaccent = 444;\n    t.Ecaron = 667;\n    t.Iogonek = 389;\n    t.kcommaaccent = 556;\n    t.minus = 570;\n    t.Icircumflex = 389;\n    t.ncaron = 556;\n    t.tcommaaccent = 333;\n    t.logicalnot = 570;\n    t.odieresis = 500;\n    t.udieresis = 556;\n    t.notequal = 549;\n    t.gcommaaccent = 500;\n    t.eth = 500;\n    t.zcaron = 444;\n    t.ncommaaccent = 556;\n    t.onesuperior = 300;\n    t.imacron = 278;\n    t.Euro = 500;\n  });\n  t[\"Times-BoldItalic\"] = getLookupTableFactory(function (t) {\n    t.space = 250;\n    t.exclam = 389;\n    t.quotedbl = 555;\n    t.numbersign = 500;\n    t.dollar = 500;\n    t.percent = 833;\n    t.ampersand = 778;\n    t.quoteright = 333;\n    t.parenleft = 333;\n    t.parenright = 333;\n    t.asterisk = 500;\n    t.plus = 570;\n    t.comma = 250;\n    t.hyphen = 333;\n    t.period = 250;\n    t.slash = 278;\n    t.zero = 500;\n    t.one = 500;\n    t.two = 500;\n    t.three = 500;\n    t.four = 500;\n    t.five = 500;\n    t.six = 500;\n    t.seven = 500;\n    t.eight = 500;\n    t.nine = 500;\n    t.colon = 333;\n    t.semicolon = 333;\n    t.less = 570;\n    t.equal = 570;\n    t.greater = 570;\n    t.question = 500;\n    t.at = 832;\n    t.A = 667;\n    t.B = 667;\n    t.C = 667;\n    t.D = 722;\n    t.E = 667;\n    t.F = 667;\n    t.G = 722;\n    t.H = 778;\n    t.I = 389;\n    t.J = 500;\n    t.K = 667;\n    t.L = 611;\n    t.M = 889;\n    t.N = 722;\n    t.O = 722;\n    t.P = 611;\n    t.Q = 722;\n    t.R = 667;\n    t.S = 556;\n    t.T = 611;\n    t.U = 722;\n    t.V = 667;\n    t.W = 889;\n    t.X = 667;\n    t.Y = 611;\n    t.Z = 611;\n    t.bracketleft = 333;\n    t.backslash = 278;\n    t.bracketright = 333;\n    t.asciicircum = 570;\n    t.underscore = 500;\n    t.quoteleft = 333;\n    t.a = 500;\n    t.b = 500;\n    t.c = 444;\n    t.d = 500;\n    t.e = 444;\n    t.f = 333;\n    t.g = 500;\n    t.h = 556;\n    t.i = 278;\n    t.j = 278;\n    t.k = 500;\n    t.l = 278;\n    t.m = 778;\n    t.n = 556;\n    t.o = 500;\n    t.p = 500;\n    t.q = 500;\n    t.r = 389;\n    t.s = 389;\n    t.t = 278;\n    t.u = 556;\n    t.v = 444;\n    t.w = 667;\n    t.x = 500;\n    t.y = 444;\n    t.z = 389;\n    t.braceleft = 348;\n    t.bar = 220;\n    t.braceright = 348;\n    t.asciitilde = 570;\n    t.exclamdown = 389;\n    t.cent = 500;\n    t.sterling = 500;\n    t.fraction = 167;\n    t.yen = 500;\n    t.florin = 500;\n    t.section = 500;\n    t.currency = 500;\n    t.quotesingle = 278;\n    t.quotedblleft = 500;\n    t.guillemotleft = 500;\n    t.guilsinglleft = 333;\n    t.guilsinglright = 333;\n    t.fi = 556;\n    t.fl = 556;\n    t.endash = 500;\n    t.dagger = 500;\n    t.daggerdbl = 500;\n    t.periodcentered = 250;\n    t.paragraph = 500;\n    t.bullet = 350;\n    t.quotesinglbase = 333;\n    t.quotedblbase = 500;\n    t.quotedblright = 500;\n    t.guillemotright = 500;\n    t.ellipsis = 1000;\n    t.perthousand = 1000;\n    t.questiondown = 500;\n    t.grave = 333;\n    t.acute = 333;\n    t.circumflex = 333;\n    t.tilde = 333;\n    t.macron = 333;\n    t.breve = 333;\n    t.dotaccent = 333;\n    t.dieresis = 333;\n    t.ring = 333;\n    t.cedilla = 333;\n    t.hungarumlaut = 333;\n    t.ogonek = 333;\n    t.caron = 333;\n    t.emdash = 1000;\n    t.AE = 944;\n    t.ordfeminine = 266;\n    t.Lslash = 611;\n    t.Oslash = 722;\n    t.OE = 944;\n    t.ordmasculine = 300;\n    t.ae = 722;\n    t.dotlessi = 278;\n    t.lslash = 278;\n    t.oslash = 500;\n    t.oe = 722;\n    t.germandbls = 500;\n    t.Idieresis = 389;\n    t.eacute = 444;\n    t.abreve = 500;\n    t.uhungarumlaut = 556;\n    t.ecaron = 444;\n    t.Ydieresis = 611;\n    t.divide = 570;\n    t.Yacute = 611;\n    t.Acircumflex = 667;\n    t.aacute = 500;\n    t.Ucircumflex = 722;\n    t.yacute = 444;\n    t.scommaaccent = 389;\n    t.ecircumflex = 444;\n    t.Uring = 722;\n    t.Udieresis = 722;\n    t.aogonek = 500;\n    t.Uacute = 722;\n    t.uogonek = 556;\n    t.Edieresis = 667;\n    t.Dcroat = 722;\n    t.commaaccent = 250;\n    t.copyright = 747;\n    t.Emacron = 667;\n    t.ccaron = 444;\n    t.aring = 500;\n    t.Ncommaaccent = 722;\n    t.lacute = 278;\n    t.agrave = 500;\n    t.Tcommaaccent = 611;\n    t.Cacute = 667;\n    t.atilde = 500;\n    t.Edotaccent = 667;\n    t.scaron = 389;\n    t.scedilla = 389;\n    t.iacute = 278;\n    t.lozenge = 494;\n    t.Rcaron = 667;\n    t.Gcommaaccent = 722;\n    t.ucircumflex = 556;\n    t.acircumflex = 500;\n    t.Amacron = 667;\n    t.rcaron = 389;\n    t.ccedilla = 444;\n    t.Zdotaccent = 611;\n    t.Thorn = 611;\n    t.Omacron = 722;\n    t.Racute = 667;\n    t.Sacute = 556;\n    t.dcaron = 608;\n    t.Umacron = 722;\n    t.uring = 556;\n    t.threesuperior = 300;\n    t.Ograve = 722;\n    t.Agrave = 667;\n    t.Abreve = 667;\n    t.multiply = 570;\n    t.uacute = 556;\n    t.Tcaron = 611;\n    t.partialdiff = 494;\n    t.ydieresis = 444;\n    t.Nacute = 722;\n    t.icircumflex = 278;\n    t.Ecircumflex = 667;\n    t.adieresis = 500;\n    t.edieresis = 444;\n    t.cacute = 444;\n    t.nacute = 556;\n    t.umacron = 556;\n    t.Ncaron = 722;\n    t.Iacute = 389;\n    t.plusminus = 570;\n    t.brokenbar = 220;\n    t.registered = 747;\n    t.Gbreve = 722;\n    t.Idotaccent = 389;\n    t.summation = 600;\n    t.Egrave = 667;\n    t.racute = 389;\n    t.omacron = 500;\n    t.Zacute = 611;\n    t.Zcaron = 611;\n    t.greaterequal = 549;\n    t.Eth = 722;\n    t.Ccedilla = 667;\n    t.lcommaaccent = 278;\n    t.tcaron = 366;\n    t.eogonek = 444;\n    t.Uogonek = 722;\n    t.Aacute = 667;\n    t.Adieresis = 667;\n    t.egrave = 444;\n    t.zacute = 389;\n    t.iogonek = 278;\n    t.Oacute = 722;\n    t.oacute = 500;\n    t.amacron = 500;\n    t.sacute = 389;\n    t.idieresis = 278;\n    t.Ocircumflex = 722;\n    t.Ugrave = 722;\n    t.Delta = 612;\n    t.thorn = 500;\n    t.twosuperior = 300;\n    t.Odieresis = 722;\n    t.mu = 576;\n    t.igrave = 278;\n    t.ohungarumlaut = 500;\n    t.Eogonek = 667;\n    t.dcroat = 500;\n    t.threequarters = 750;\n    t.Scedilla = 556;\n    t.lcaron = 382;\n    t.Kcommaaccent = 667;\n    t.Lacute = 611;\n    t.trademark = 1000;\n    t.edotaccent = 444;\n    t.Igrave = 389;\n    t.Imacron = 389;\n    t.Lcaron = 611;\n    t.onehalf = 750;\n    t.lessequal = 549;\n    t.ocircumflex = 500;\n    t.ntilde = 556;\n    t.Uhungarumlaut = 722;\n    t.Eacute = 667;\n    t.emacron = 444;\n    t.gbreve = 500;\n    t.onequarter = 750;\n    t.Scaron = 556;\n    t.Scommaaccent = 556;\n    t.Ohungarumlaut = 722;\n    t.degree = 400;\n    t.ograve = 500;\n    t.Ccaron = 667;\n    t.ugrave = 556;\n    t.radical = 549;\n    t.Dcaron = 722;\n    t.rcommaaccent = 389;\n    t.Ntilde = 722;\n    t.otilde = 500;\n    t.Rcommaaccent = 667;\n    t.Lcommaaccent = 611;\n    t.Atilde = 667;\n    t.Aogonek = 667;\n    t.Aring = 667;\n    t.Otilde = 722;\n    t.zdotaccent = 389;\n    t.Ecaron = 667;\n    t.Iogonek = 389;\n    t.kcommaaccent = 500;\n    t.minus = 606;\n    t.Icircumflex = 389;\n    t.ncaron = 556;\n    t.tcommaaccent = 278;\n    t.logicalnot = 606;\n    t.odieresis = 500;\n    t.udieresis = 556;\n    t.notequal = 549;\n    t.gcommaaccent = 500;\n    t.eth = 500;\n    t.zcaron = 389;\n    t.ncommaaccent = 556;\n    t.onesuperior = 300;\n    t.imacron = 278;\n    t.Euro = 500;\n  });\n  t[\"Times-Italic\"] = getLookupTableFactory(function (t) {\n    t.space = 250;\n    t.exclam = 333;\n    t.quotedbl = 420;\n    t.numbersign = 500;\n    t.dollar = 500;\n    t.percent = 833;\n    t.ampersand = 778;\n    t.quoteright = 333;\n    t.parenleft = 333;\n    t.parenright = 333;\n    t.asterisk = 500;\n    t.plus = 675;\n    t.comma = 250;\n    t.hyphen = 333;\n    t.period = 250;\n    t.slash = 278;\n    t.zero = 500;\n    t.one = 500;\n    t.two = 500;\n    t.three = 500;\n    t.four = 500;\n    t.five = 500;\n    t.six = 500;\n    t.seven = 500;\n    t.eight = 500;\n    t.nine = 500;\n    t.colon = 333;\n    t.semicolon = 333;\n    t.less = 675;\n    t.equal = 675;\n    t.greater = 675;\n    t.question = 500;\n    t.at = 920;\n    t.A = 611;\n    t.B = 611;\n    t.C = 667;\n    t.D = 722;\n    t.E = 611;\n    t.F = 611;\n    t.G = 722;\n    t.H = 722;\n    t.I = 333;\n    t.J = 444;\n    t.K = 667;\n    t.L = 556;\n    t.M = 833;\n    t.N = 667;\n    t.O = 722;\n    t.P = 611;\n    t.Q = 722;\n    t.R = 611;\n    t.S = 500;\n    t.T = 556;\n    t.U = 722;\n    t.V = 611;\n    t.W = 833;\n    t.X = 611;\n    t.Y = 556;\n    t.Z = 556;\n    t.bracketleft = 389;\n    t.backslash = 278;\n    t.bracketright = 389;\n    t.asciicircum = 422;\n    t.underscore = 500;\n    t.quoteleft = 333;\n    t.a = 500;\n    t.b = 500;\n    t.c = 444;\n    t.d = 500;\n    t.e = 444;\n    t.f = 278;\n    t.g = 500;\n    t.h = 500;\n    t.i = 278;\n    t.j = 278;\n    t.k = 444;\n    t.l = 278;\n    t.m = 722;\n    t.n = 500;\n    t.o = 500;\n    t.p = 500;\n    t.q = 500;\n    t.r = 389;\n    t.s = 389;\n    t.t = 278;\n    t.u = 500;\n    t.v = 444;\n    t.w = 667;\n    t.x = 444;\n    t.y = 444;\n    t.z = 389;\n    t.braceleft = 400;\n    t.bar = 275;\n    t.braceright = 400;\n    t.asciitilde = 541;\n    t.exclamdown = 389;\n    t.cent = 500;\n    t.sterling = 500;\n    t.fraction = 167;\n    t.yen = 500;\n    t.florin = 500;\n    t.section = 500;\n    t.currency = 500;\n    t.quotesingle = 214;\n    t.quotedblleft = 556;\n    t.guillemotleft = 500;\n    t.guilsinglleft = 333;\n    t.guilsinglright = 333;\n    t.fi = 500;\n    t.fl = 500;\n    t.endash = 500;\n    t.dagger = 500;\n    t.daggerdbl = 500;\n    t.periodcentered = 250;\n    t.paragraph = 523;\n    t.bullet = 350;\n    t.quotesinglbase = 333;\n    t.quotedblbase = 556;\n    t.quotedblright = 556;\n    t.guillemotright = 500;\n    t.ellipsis = 889;\n    t.perthousand = 1000;\n    t.questiondown = 500;\n    t.grave = 333;\n    t.acute = 333;\n    t.circumflex = 333;\n    t.tilde = 333;\n    t.macron = 333;\n    t.breve = 333;\n    t.dotaccent = 333;\n    t.dieresis = 333;\n    t.ring = 333;\n    t.cedilla = 333;\n    t.hungarumlaut = 333;\n    t.ogonek = 333;\n    t.caron = 333;\n    t.emdash = 889;\n    t.AE = 889;\n    t.ordfeminine = 276;\n    t.Lslash = 556;\n    t.Oslash = 722;\n    t.OE = 944;\n    t.ordmasculine = 310;\n    t.ae = 667;\n    t.dotlessi = 278;\n    t.lslash = 278;\n    t.oslash = 500;\n    t.oe = 667;\n    t.germandbls = 500;\n    t.Idieresis = 333;\n    t.eacute = 444;\n    t.abreve = 500;\n    t.uhungarumlaut = 500;\n    t.ecaron = 444;\n    t.Ydieresis = 556;\n    t.divide = 675;\n    t.Yacute = 556;\n    t.Acircumflex = 611;\n    t.aacute = 500;\n    t.Ucircumflex = 722;\n    t.yacute = 444;\n    t.scommaaccent = 389;\n    t.ecircumflex = 444;\n    t.Uring = 722;\n    t.Udieresis = 722;\n    t.aogonek = 500;\n    t.Uacute = 722;\n    t.uogonek = 500;\n    t.Edieresis = 611;\n    t.Dcroat = 722;\n    t.commaaccent = 250;\n    t.copyright = 760;\n    t.Emacron = 611;\n    t.ccaron = 444;\n    t.aring = 500;\n    t.Ncommaaccent = 667;\n    t.lacute = 278;\n    t.agrave = 500;\n    t.Tcommaaccent = 556;\n    t.Cacute = 667;\n    t.atilde = 500;\n    t.Edotaccent = 611;\n    t.scaron = 389;\n    t.scedilla = 389;\n    t.iacute = 278;\n    t.lozenge = 471;\n    t.Rcaron = 611;\n    t.Gcommaaccent = 722;\n    t.ucircumflex = 500;\n    t.acircumflex = 500;\n    t.Amacron = 611;\n    t.rcaron = 389;\n    t.ccedilla = 444;\n    t.Zdotaccent = 556;\n    t.Thorn = 611;\n    t.Omacron = 722;\n    t.Racute = 611;\n    t.Sacute = 500;\n    t.dcaron = 544;\n    t.Umacron = 722;\n    t.uring = 500;\n    t.threesuperior = 300;\n    t.Ograve = 722;\n    t.Agrave = 611;\n    t.Abreve = 611;\n    t.multiply = 675;\n    t.uacute = 500;\n    t.Tcaron = 556;\n    t.partialdiff = 476;\n    t.ydieresis = 444;\n    t.Nacute = 667;\n    t.icircumflex = 278;\n    t.Ecircumflex = 611;\n    t.adieresis = 500;\n    t.edieresis = 444;\n    t.cacute = 444;\n    t.nacute = 500;\n    t.umacron = 500;\n    t.Ncaron = 667;\n    t.Iacute = 333;\n    t.plusminus = 675;\n    t.brokenbar = 275;\n    t.registered = 760;\n    t.Gbreve = 722;\n    t.Idotaccent = 333;\n    t.summation = 600;\n    t.Egrave = 611;\n    t.racute = 389;\n    t.omacron = 500;\n    t.Zacute = 556;\n    t.Zcaron = 556;\n    t.greaterequal = 549;\n    t.Eth = 722;\n    t.Ccedilla = 667;\n    t.lcommaaccent = 278;\n    t.tcaron = 300;\n    t.eogonek = 444;\n    t.Uogonek = 722;\n    t.Aacute = 611;\n    t.Adieresis = 611;\n    t.egrave = 444;\n    t.zacute = 389;\n    t.iogonek = 278;\n    t.Oacute = 722;\n    t.oacute = 500;\n    t.amacron = 500;\n    t.sacute = 389;\n    t.idieresis = 278;\n    t.Ocircumflex = 722;\n    t.Ugrave = 722;\n    t.Delta = 612;\n    t.thorn = 500;\n    t.twosuperior = 300;\n    t.Odieresis = 722;\n    t.mu = 500;\n    t.igrave = 278;\n    t.ohungarumlaut = 500;\n    t.Eogonek = 611;\n    t.dcroat = 500;\n    t.threequarters = 750;\n    t.Scedilla = 500;\n    t.lcaron = 300;\n    t.Kcommaaccent = 667;\n    t.Lacute = 556;\n    t.trademark = 980;\n    t.edotaccent = 444;\n    t.Igrave = 333;\n    t.Imacron = 333;\n    t.Lcaron = 611;\n    t.onehalf = 750;\n    t.lessequal = 549;\n    t.ocircumflex = 500;\n    t.ntilde = 500;\n    t.Uhungarumlaut = 722;\n    t.Eacute = 611;\n    t.emacron = 444;\n    t.gbreve = 500;\n    t.onequarter = 750;\n    t.Scaron = 500;\n    t.Scommaaccent = 500;\n    t.Ohungarumlaut = 722;\n    t.degree = 400;\n    t.ograve = 500;\n    t.Ccaron = 667;\n    t.ugrave = 500;\n    t.radical = 453;\n    t.Dcaron = 722;\n    t.rcommaaccent = 389;\n    t.Ntilde = 667;\n    t.otilde = 500;\n    t.Rcommaaccent = 611;\n    t.Lcommaaccent = 556;\n    t.Atilde = 611;\n    t.Aogonek = 611;\n    t.Aring = 611;\n    t.Otilde = 722;\n    t.zdotaccent = 389;\n    t.Ecaron = 611;\n    t.Iogonek = 333;\n    t.kcommaaccent = 444;\n    t.minus = 675;\n    t.Icircumflex = 333;\n    t.ncaron = 500;\n    t.tcommaaccent = 278;\n    t.logicalnot = 675;\n    t.odieresis = 500;\n    t.udieresis = 500;\n    t.notequal = 549;\n    t.gcommaaccent = 500;\n    t.eth = 500;\n    t.zcaron = 389;\n    t.ncommaaccent = 500;\n    t.onesuperior = 300;\n    t.imacron = 278;\n    t.Euro = 500;\n  });\n  t.ZapfDingbats = getLookupTableFactory(function (t) {\n    t.space = 278;\n    t.a1 = 974;\n    t.a2 = 961;\n    t.a202 = 974;\n    t.a3 = 980;\n    t.a4 = 719;\n    t.a5 = 789;\n    t.a119 = 790;\n    t.a118 = 791;\n    t.a117 = 690;\n    t.a11 = 960;\n    t.a12 = 939;\n    t.a13 = 549;\n    t.a14 = 855;\n    t.a15 = 911;\n    t.a16 = 933;\n    t.a105 = 911;\n    t.a17 = 945;\n    t.a18 = 974;\n    t.a19 = 755;\n    t.a20 = 846;\n    t.a21 = 762;\n    t.a22 = 761;\n    t.a23 = 571;\n    t.a24 = 677;\n    t.a25 = 763;\n    t.a26 = 760;\n    t.a27 = 759;\n    t.a28 = 754;\n    t.a6 = 494;\n    t.a7 = 552;\n    t.a8 = 537;\n    t.a9 = 577;\n    t.a10 = 692;\n    t.a29 = 786;\n    t.a30 = 788;\n    t.a31 = 788;\n    t.a32 = 790;\n    t.a33 = 793;\n    t.a34 = 794;\n    t.a35 = 816;\n    t.a36 = 823;\n    t.a37 = 789;\n    t.a38 = 841;\n    t.a39 = 823;\n    t.a40 = 833;\n    t.a41 = 816;\n    t.a42 = 831;\n    t.a43 = 923;\n    t.a44 = 744;\n    t.a45 = 723;\n    t.a46 = 749;\n    t.a47 = 790;\n    t.a48 = 792;\n    t.a49 = 695;\n    t.a50 = 776;\n    t.a51 = 768;\n    t.a52 = 792;\n    t.a53 = 759;\n    t.a54 = 707;\n    t.a55 = 708;\n    t.a56 = 682;\n    t.a57 = 701;\n    t.a58 = 826;\n    t.a59 = 815;\n    t.a60 = 789;\n    t.a61 = 789;\n    t.a62 = 707;\n    t.a63 = 687;\n    t.a64 = 696;\n    t.a65 = 689;\n    t.a66 = 786;\n    t.a67 = 787;\n    t.a68 = 713;\n    t.a69 = 791;\n    t.a70 = 785;\n    t.a71 = 791;\n    t.a72 = 873;\n    t.a73 = 761;\n    t.a74 = 762;\n    t.a203 = 762;\n    t.a75 = 759;\n    t.a204 = 759;\n    t.a76 = 892;\n    t.a77 = 892;\n    t.a78 = 788;\n    t.a79 = 784;\n    t.a81 = 438;\n    t.a82 = 138;\n    t.a83 = 277;\n    t.a84 = 415;\n    t.a97 = 392;\n    t.a98 = 392;\n    t.a99 = 668;\n    t.a100 = 668;\n    t.a89 = 390;\n    t.a90 = 390;\n    t.a93 = 317;\n    t.a94 = 317;\n    t.a91 = 276;\n    t.a92 = 276;\n    t.a205 = 509;\n    t.a85 = 509;\n    t.a206 = 410;\n    t.a86 = 410;\n    t.a87 = 234;\n    t.a88 = 234;\n    t.a95 = 334;\n    t.a96 = 334;\n    t.a101 = 732;\n    t.a102 = 544;\n    t.a103 = 544;\n    t.a104 = 910;\n    t.a106 = 667;\n    t.a107 = 760;\n    t.a108 = 760;\n    t.a112 = 776;\n    t.a111 = 595;\n    t.a110 = 694;\n    t.a109 = 626;\n    t.a120 = 788;\n    t.a121 = 788;\n    t.a122 = 788;\n    t.a123 = 788;\n    t.a124 = 788;\n    t.a125 = 788;\n    t.a126 = 788;\n    t.a127 = 788;\n    t.a128 = 788;\n    t.a129 = 788;\n    t.a130 = 788;\n    t.a131 = 788;\n    t.a132 = 788;\n    t.a133 = 788;\n    t.a134 = 788;\n    t.a135 = 788;\n    t.a136 = 788;\n    t.a137 = 788;\n    t.a138 = 788;\n    t.a139 = 788;\n    t.a140 = 788;\n    t.a141 = 788;\n    t.a142 = 788;\n    t.a143 = 788;\n    t.a144 = 788;\n    t.a145 = 788;\n    t.a146 = 788;\n    t.a147 = 788;\n    t.a148 = 788;\n    t.a149 = 788;\n    t.a150 = 788;\n    t.a151 = 788;\n    t.a152 = 788;\n    t.a153 = 788;\n    t.a154 = 788;\n    t.a155 = 788;\n    t.a156 = 788;\n    t.a157 = 788;\n    t.a158 = 788;\n    t.a159 = 788;\n    t.a160 = 894;\n    t.a161 = 838;\n    t.a163 = 1016;\n    t.a164 = 458;\n    t.a196 = 748;\n    t.a165 = 924;\n    t.a192 = 748;\n    t.a166 = 918;\n    t.a167 = 927;\n    t.a168 = 928;\n    t.a169 = 928;\n    t.a170 = 834;\n    t.a171 = 873;\n    t.a172 = 828;\n    t.a173 = 924;\n    t.a162 = 924;\n    t.a174 = 917;\n    t.a175 = 930;\n    t.a176 = 931;\n    t.a177 = 463;\n    t.a178 = 883;\n    t.a179 = 836;\n    t.a193 = 836;\n    t.a180 = 867;\n    t.a199 = 867;\n    t.a181 = 696;\n    t.a200 = 696;\n    t.a182 = 874;\n    t.a201 = 874;\n    t.a183 = 760;\n    t.a184 = 946;\n    t.a197 = 771;\n    t.a185 = 865;\n    t.a194 = 771;\n    t.a198 = 888;\n    t.a186 = 967;\n    t.a195 = 888;\n    t.a187 = 831;\n    t.a188 = 873;\n    t.a189 = 927;\n    t.a190 = 970;\n    t.a191 = 918;\n  });\n});\nconst getFontBasicMetrics = getLookupTableFactory(function (t) {\n  t.Courier = {\n    ascent: 629,\n    descent: -157,\n    capHeight: 562,\n    xHeight: -426\n  };\n  t[\"Courier-Bold\"] = {\n    ascent: 629,\n    descent: -157,\n    capHeight: 562,\n    xHeight: 439\n  };\n  t[\"Courier-Oblique\"] = {\n    ascent: 629,\n    descent: -157,\n    capHeight: 562,\n    xHeight: 426\n  };\n  t[\"Courier-BoldOblique\"] = {\n    ascent: 629,\n    descent: -157,\n    capHeight: 562,\n    xHeight: 426\n  };\n  t.Helvetica = {\n    ascent: 718,\n    descent: -207,\n    capHeight: 718,\n    xHeight: 523\n  };\n  t[\"Helvetica-Bold\"] = {\n    ascent: 718,\n    descent: -207,\n    capHeight: 718,\n    xHeight: 532\n  };\n  t[\"Helvetica-Oblique\"] = {\n    ascent: 718,\n    descent: -207,\n    capHeight: 718,\n    xHeight: 523\n  };\n  t[\"Helvetica-BoldOblique\"] = {\n    ascent: 718,\n    descent: -207,\n    capHeight: 718,\n    xHeight: 532\n  };\n  t[\"Times-Roman\"] = {\n    ascent: 683,\n    descent: -217,\n    capHeight: 662,\n    xHeight: 450\n  };\n  t[\"Times-Bold\"] = {\n    ascent: 683,\n    descent: -217,\n    capHeight: 676,\n    xHeight: 461\n  };\n  t[\"Times-Italic\"] = {\n    ascent: 683,\n    descent: -217,\n    capHeight: 653,\n    xHeight: 441\n  };\n  t[\"Times-BoldItalic\"] = {\n    ascent: 683,\n    descent: -217,\n    capHeight: 669,\n    xHeight: 462\n  };\n  t.Symbol = {\n    ascent: Math.NaN,\n    descent: Math.NaN,\n    capHeight: Math.NaN,\n    xHeight: Math.NaN\n  };\n  t.ZapfDingbats = {\n    ascent: Math.NaN,\n    descent: Math.NaN,\n    capHeight: Math.NaN,\n    xHeight: Math.NaN\n  };\n});\n\n;// ./src/core/glyf.js\nconst ON_CURVE_POINT = 1 << 0;\nconst X_SHORT_VECTOR = 1 << 1;\nconst Y_SHORT_VECTOR = 1 << 2;\nconst REPEAT_FLAG = 1 << 3;\nconst X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR = 1 << 4;\nconst Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR = 1 << 5;\nconst OVERLAP_SIMPLE = 1 << 6;\nconst ARG_1_AND_2_ARE_WORDS = 1 << 0;\nconst ARGS_ARE_XY_VALUES = 1 << 1;\nconst WE_HAVE_A_SCALE = 1 << 3;\nconst MORE_COMPONENTS = 1 << 5;\nconst WE_HAVE_AN_X_AND_Y_SCALE = 1 << 6;\nconst WE_HAVE_A_TWO_BY_TWO = 1 << 7;\nconst WE_HAVE_INSTRUCTIONS = 1 << 8;\nclass GlyfTable {\n  constructor({\n    glyfTable,\n    isGlyphLocationsLong,\n    locaTable,\n    numGlyphs\n  }) {\n    this.glyphs = [];\n    const loca = new DataView(locaTable.buffer, locaTable.byteOffset, locaTable.byteLength);\n    const glyf = new DataView(glyfTable.buffer, glyfTable.byteOffset, glyfTable.byteLength);\n    const offsetSize = isGlyphLocationsLong ? 4 : 2;\n    let prev = isGlyphLocationsLong ? loca.getUint32(0) : 2 * loca.getUint16(0);\n    let pos = 0;\n    for (let i = 0; i < numGlyphs; i++) {\n      pos += offsetSize;\n      const next = isGlyphLocationsLong ? loca.getUint32(pos) : 2 * loca.getUint16(pos);\n      if (next === prev) {\n        this.glyphs.push(new Glyph({}));\n        continue;\n      }\n      const glyph = Glyph.parse(prev, glyf);\n      this.glyphs.push(glyph);\n      prev = next;\n    }\n  }\n  getSize() {\n    return this.glyphs.reduce((a, g) => {\n      const size = g.getSize();\n      return a + (size + 3 & ~3);\n    }, 0);\n  }\n  write() {\n    const totalSize = this.getSize();\n    const glyfTable = new DataView(new ArrayBuffer(totalSize));\n    const isLocationLong = totalSize > 0x1fffe;\n    const offsetSize = isLocationLong ? 4 : 2;\n    const locaTable = new DataView(new ArrayBuffer((this.glyphs.length + 1) * offsetSize));\n    if (isLocationLong) {\n      locaTable.setUint32(0, 0);\n    } else {\n      locaTable.setUint16(0, 0);\n    }\n    let pos = 0;\n    let locaIndex = 0;\n    for (const glyph of this.glyphs) {\n      pos += glyph.write(pos, glyfTable);\n      pos = pos + 3 & ~3;\n      locaIndex += offsetSize;\n      if (isLocationLong) {\n        locaTable.setUint32(locaIndex, pos);\n      } else {\n        locaTable.setUint16(locaIndex, pos >> 1);\n      }\n    }\n    return {\n      isLocationLong,\n      loca: new Uint8Array(locaTable.buffer),\n      glyf: new Uint8Array(glyfTable.buffer)\n    };\n  }\n  scale(factors) {\n    for (let i = 0, ii = this.glyphs.length; i < ii; i++) {\n      this.glyphs[i].scale(factors[i]);\n    }\n  }\n}\nclass Glyph {\n  constructor({\n    header = null,\n    simple = null,\n    composites = null\n  }) {\n    this.header = header;\n    this.simple = simple;\n    this.composites = composites;\n  }\n  static parse(pos, glyf) {\n    const [read, header] = GlyphHeader.parse(pos, glyf);\n    pos += read;\n    if (header.numberOfContours < 0) {\n      const composites = [];\n      while (true) {\n        const [n, composite] = CompositeGlyph.parse(pos, glyf);\n        pos += n;\n        composites.push(composite);\n        if (!(composite.flags & MORE_COMPONENTS)) {\n          break;\n        }\n      }\n      return new Glyph({\n        header,\n        composites\n      });\n    }\n    const simple = SimpleGlyph.parse(pos, glyf, header.numberOfContours);\n    return new Glyph({\n      header,\n      simple\n    });\n  }\n  getSize() {\n    if (!this.header) {\n      return 0;\n    }\n    const size = this.simple ? this.simple.getSize() : this.composites.reduce((a, c) => a + c.getSize(), 0);\n    return this.header.getSize() + size;\n  }\n  write(pos, buf) {\n    if (!this.header) {\n      return 0;\n    }\n    const spos = pos;\n    pos += this.header.write(pos, buf);\n    if (this.simple) {\n      pos += this.simple.write(pos, buf);\n    } else {\n      for (const composite of this.composites) {\n        pos += composite.write(pos, buf);\n      }\n    }\n    return pos - spos;\n  }\n  scale(factor) {\n    if (!this.header) {\n      return;\n    }\n    const xMiddle = (this.header.xMin + this.header.xMax) / 2;\n    this.header.scale(xMiddle, factor);\n    if (this.simple) {\n      this.simple.scale(xMiddle, factor);\n    } else {\n      for (const composite of this.composites) {\n        composite.scale(xMiddle, factor);\n      }\n    }\n  }\n}\nclass GlyphHeader {\n  constructor({\n    numberOfContours,\n    xMin,\n    yMin,\n    xMax,\n    yMax\n  }) {\n    this.numberOfContours = numberOfContours;\n    this.xMin = xMin;\n    this.yMin = yMin;\n    this.xMax = xMax;\n    this.yMax = yMax;\n  }\n  static parse(pos, glyf) {\n    return [10, new GlyphHeader({\n      numberOfContours: glyf.getInt16(pos),\n      xMin: glyf.getInt16(pos + 2),\n      yMin: glyf.getInt16(pos + 4),\n      xMax: glyf.getInt16(pos + 6),\n      yMax: glyf.getInt16(pos + 8)\n    })];\n  }\n  getSize() {\n    return 10;\n  }\n  write(pos, buf) {\n    buf.setInt16(pos, this.numberOfContours);\n    buf.setInt16(pos + 2, this.xMin);\n    buf.setInt16(pos + 4, this.yMin);\n    buf.setInt16(pos + 6, this.xMax);\n    buf.setInt16(pos + 8, this.yMax);\n    return 10;\n  }\n  scale(x, factor) {\n    this.xMin = Math.round(x + (this.xMin - x) * factor);\n    this.xMax = Math.round(x + (this.xMax - x) * factor);\n  }\n}\nclass Contour {\n  constructor({\n    flags,\n    xCoordinates,\n    yCoordinates\n  }) {\n    this.xCoordinates = xCoordinates;\n    this.yCoordinates = yCoordinates;\n    this.flags = flags;\n  }\n}\nclass SimpleGlyph {\n  constructor({\n    contours,\n    instructions\n  }) {\n    this.contours = contours;\n    this.instructions = instructions;\n  }\n  static parse(pos, glyf, numberOfContours) {\n    const endPtsOfContours = [];\n    for (let i = 0; i < numberOfContours; i++) {\n      const endPt = glyf.getUint16(pos);\n      pos += 2;\n      endPtsOfContours.push(endPt);\n    }\n    const numberOfPt = endPtsOfContours[numberOfContours - 1] + 1;\n    const instructionLength = glyf.getUint16(pos);\n    pos += 2;\n    const instructions = new Uint8Array(glyf).slice(pos, pos + instructionLength);\n    pos += instructionLength;\n    const flags = [];\n    for (let i = 0; i < numberOfPt; pos++, i++) {\n      let flag = glyf.getUint8(pos);\n      flags.push(flag);\n      if (flag & REPEAT_FLAG) {\n        const count = glyf.getUint8(++pos);\n        flag ^= REPEAT_FLAG;\n        for (let m = 0; m < count; m++) {\n          flags.push(flag);\n        }\n        i += count;\n      }\n    }\n    const allXCoordinates = [];\n    let xCoordinates = [];\n    let yCoordinates = [];\n    let pointFlags = [];\n    const contours = [];\n    let endPtsOfContoursIndex = 0;\n    let lastCoordinate = 0;\n    for (let i = 0; i < numberOfPt; i++) {\n      const flag = flags[i];\n      if (flag & X_SHORT_VECTOR) {\n        const x = glyf.getUint8(pos++);\n        lastCoordinate += flag & X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR ? x : -x;\n        xCoordinates.push(lastCoordinate);\n      } else if (flag & X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR) {\n        xCoordinates.push(lastCoordinate);\n      } else {\n        lastCoordinate += glyf.getInt16(pos);\n        pos += 2;\n        xCoordinates.push(lastCoordinate);\n      }\n      if (endPtsOfContours[endPtsOfContoursIndex] === i) {\n        endPtsOfContoursIndex++;\n        allXCoordinates.push(xCoordinates);\n        xCoordinates = [];\n      }\n    }\n    lastCoordinate = 0;\n    endPtsOfContoursIndex = 0;\n    for (let i = 0; i < numberOfPt; i++) {\n      const flag = flags[i];\n      if (flag & Y_SHORT_VECTOR) {\n        const y = glyf.getUint8(pos++);\n        lastCoordinate += flag & Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR ? y : -y;\n        yCoordinates.push(lastCoordinate);\n      } else if (flag & Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR) {\n        yCoordinates.push(lastCoordinate);\n      } else {\n        lastCoordinate += glyf.getInt16(pos);\n        pos += 2;\n        yCoordinates.push(lastCoordinate);\n      }\n      pointFlags.push(flag & ON_CURVE_POINT | flag & OVERLAP_SIMPLE);\n      if (endPtsOfContours[endPtsOfContoursIndex] === i) {\n        xCoordinates = allXCoordinates[endPtsOfContoursIndex];\n        endPtsOfContoursIndex++;\n        contours.push(new Contour({\n          flags: pointFlags,\n          xCoordinates,\n          yCoordinates\n        }));\n        yCoordinates = [];\n        pointFlags = [];\n      }\n    }\n    return new SimpleGlyph({\n      contours,\n      instructions\n    });\n  }\n  getSize() {\n    let size = this.contours.length * 2 + 2 + this.instructions.length;\n    let lastX = 0;\n    let lastY = 0;\n    for (const contour of this.contours) {\n      size += contour.flags.length;\n      for (let i = 0, ii = contour.xCoordinates.length; i < ii; i++) {\n        const x = contour.xCoordinates[i];\n        const y = contour.yCoordinates[i];\n        let abs = Math.abs(x - lastX);\n        if (abs > 255) {\n          size += 2;\n        } else if (abs > 0) {\n          size += 1;\n        }\n        lastX = x;\n        abs = Math.abs(y - lastY);\n        if (abs > 255) {\n          size += 2;\n        } else if (abs > 0) {\n          size += 1;\n        }\n        lastY = y;\n      }\n    }\n    return size;\n  }\n  write(pos, buf) {\n    const spos = pos;\n    const xCoordinates = [];\n    const yCoordinates = [];\n    const flags = [];\n    let lastX = 0;\n    let lastY = 0;\n    for (const contour of this.contours) {\n      for (let i = 0, ii = contour.xCoordinates.length; i < ii; i++) {\n        let flag = contour.flags[i];\n        const x = contour.xCoordinates[i];\n        let delta = x - lastX;\n        if (delta === 0) {\n          flag |= X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR;\n          xCoordinates.push(0);\n        } else {\n          const abs = Math.abs(delta);\n          if (abs <= 255) {\n            flag |= delta >= 0 ? X_SHORT_VECTOR | X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR : X_SHORT_VECTOR;\n            xCoordinates.push(abs);\n          } else {\n            xCoordinates.push(delta);\n          }\n        }\n        lastX = x;\n        const y = contour.yCoordinates[i];\n        delta = y - lastY;\n        if (delta === 0) {\n          flag |= Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR;\n          yCoordinates.push(0);\n        } else {\n          const abs = Math.abs(delta);\n          if (abs <= 255) {\n            flag |= delta >= 0 ? Y_SHORT_VECTOR | Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR : Y_SHORT_VECTOR;\n            yCoordinates.push(abs);\n          } else {\n            yCoordinates.push(delta);\n          }\n        }\n        lastY = y;\n        flags.push(flag);\n      }\n      buf.setUint16(pos, xCoordinates.length - 1);\n      pos += 2;\n    }\n    buf.setUint16(pos, this.instructions.length);\n    pos += 2;\n    if (this.instructions.length) {\n      new Uint8Array(buf.buffer, 0, buf.buffer.byteLength).set(this.instructions, pos);\n      pos += this.instructions.length;\n    }\n    for (const flag of flags) {\n      buf.setUint8(pos++, flag);\n    }\n    for (let i = 0, ii = xCoordinates.length; i < ii; i++) {\n      const x = xCoordinates[i];\n      const flag = flags[i];\n      if (flag & X_SHORT_VECTOR) {\n        buf.setUint8(pos++, x);\n      } else if (!(flag & X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR)) {\n        buf.setInt16(pos, x);\n        pos += 2;\n      }\n    }\n    for (let i = 0, ii = yCoordinates.length; i < ii; i++) {\n      const y = yCoordinates[i];\n      const flag = flags[i];\n      if (flag & Y_SHORT_VECTOR) {\n        buf.setUint8(pos++, y);\n      } else if (!(flag & Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR)) {\n        buf.setInt16(pos, y);\n        pos += 2;\n      }\n    }\n    return pos - spos;\n  }\n  scale(x, factor) {\n    for (const contour of this.contours) {\n      if (contour.xCoordinates.length === 0) {\n        continue;\n      }\n      for (let i = 0, ii = contour.xCoordinates.length; i < ii; i++) {\n        contour.xCoordinates[i] = Math.round(x + (contour.xCoordinates[i] - x) * factor);\n      }\n    }\n  }\n}\nclass CompositeGlyph {\n  constructor({\n    flags,\n    glyphIndex,\n    argument1,\n    argument2,\n    transf,\n    instructions\n  }) {\n    this.flags = flags;\n    this.glyphIndex = glyphIndex;\n    this.argument1 = argument1;\n    this.argument2 = argument2;\n    this.transf = transf;\n    this.instructions = instructions;\n  }\n  static parse(pos, glyf) {\n    const spos = pos;\n    const transf = [];\n    let flags = glyf.getUint16(pos);\n    const glyphIndex = glyf.getUint16(pos + 2);\n    pos += 4;\n    let argument1, argument2;\n    if (flags & ARG_1_AND_2_ARE_WORDS) {\n      if (flags & ARGS_ARE_XY_VALUES) {\n        argument1 = glyf.getInt16(pos);\n        argument2 = glyf.getInt16(pos + 2);\n      } else {\n        argument1 = glyf.getUint16(pos);\n        argument2 = glyf.getUint16(pos + 2);\n      }\n      pos += 4;\n      flags ^= ARG_1_AND_2_ARE_WORDS;\n    } else {\n      if (flags & ARGS_ARE_XY_VALUES) {\n        argument1 = glyf.getInt8(pos);\n        argument2 = glyf.getInt8(pos + 1);\n      } else {\n        argument1 = glyf.getUint8(pos);\n        argument2 = glyf.getUint8(pos + 1);\n      }\n      pos += 2;\n    }\n    if (flags & WE_HAVE_A_SCALE) {\n      transf.push(glyf.getUint16(pos));\n      pos += 2;\n    } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {\n      transf.push(glyf.getUint16(pos), glyf.getUint16(pos + 2));\n      pos += 4;\n    } else if (flags & WE_HAVE_A_TWO_BY_TWO) {\n      transf.push(glyf.getUint16(pos), glyf.getUint16(pos + 2), glyf.getUint16(pos + 4), glyf.getUint16(pos + 6));\n      pos += 8;\n    }\n    let instructions = null;\n    if (flags & WE_HAVE_INSTRUCTIONS) {\n      const instructionLength = glyf.getUint16(pos);\n      pos += 2;\n      instructions = new Uint8Array(glyf).slice(pos, pos + instructionLength);\n      pos += instructionLength;\n    }\n    return [pos - spos, new CompositeGlyph({\n      flags,\n      glyphIndex,\n      argument1,\n      argument2,\n      transf,\n      instructions\n    })];\n  }\n  getSize() {\n    let size = 2 + 2 + this.transf.length * 2;\n    if (this.flags & WE_HAVE_INSTRUCTIONS) {\n      size += 2 + this.instructions.length;\n    }\n    size += 2;\n    if (this.flags & 2) {\n      if (!(this.argument1 >= -128 && this.argument1 <= 127 && this.argument2 >= -128 && this.argument2 <= 127)) {\n        size += 2;\n      }\n    } else if (!(this.argument1 >= 0 && this.argument1 <= 255 && this.argument2 >= 0 && this.argument2 <= 255)) {\n      size += 2;\n    }\n    return size;\n  }\n  write(pos, buf) {\n    const spos = pos;\n    if (this.flags & ARGS_ARE_XY_VALUES) {\n      if (!(this.argument1 >= -128 && this.argument1 <= 127 && this.argument2 >= -128 && this.argument2 <= 127)) {\n        this.flags |= ARG_1_AND_2_ARE_WORDS;\n      }\n    } else if (!(this.argument1 >= 0 && this.argument1 <= 255 && this.argument2 >= 0 && this.argument2 <= 255)) {\n      this.flags |= ARG_1_AND_2_ARE_WORDS;\n    }\n    buf.setUint16(pos, this.flags);\n    buf.setUint16(pos + 2, this.glyphIndex);\n    pos += 4;\n    if (this.flags & ARG_1_AND_2_ARE_WORDS) {\n      if (this.flags & ARGS_ARE_XY_VALUES) {\n        buf.setInt16(pos, this.argument1);\n        buf.setInt16(pos + 2, this.argument2);\n      } else {\n        buf.setUint16(pos, this.argument1);\n        buf.setUint16(pos + 2, this.argument2);\n      }\n      pos += 4;\n    } else {\n      buf.setUint8(pos, this.argument1);\n      buf.setUint8(pos + 1, this.argument2);\n      pos += 2;\n    }\n    if (this.flags & WE_HAVE_INSTRUCTIONS) {\n      buf.setUint16(pos, this.instructions.length);\n      pos += 2;\n      if (this.instructions.length) {\n        new Uint8Array(buf.buffer, 0, buf.buffer.byteLength).set(this.instructions, pos);\n        pos += this.instructions.length;\n      }\n    }\n    return pos - spos;\n  }\n  scale(x, factor) {}\n}\n\n;// ./src/core/opentype_file_builder.js\n\n\nfunction writeInt16(dest, offset, num) {\n  dest[offset] = num >> 8 & 0xff;\n  dest[offset + 1] = num & 0xff;\n}\nfunction writeInt32(dest, offset, num) {\n  dest[offset] = num >> 24 & 0xff;\n  dest[offset + 1] = num >> 16 & 0xff;\n  dest[offset + 2] = num >> 8 & 0xff;\n  dest[offset + 3] = num & 0xff;\n}\nfunction writeData(dest, offset, data) {\n  if (data instanceof Uint8Array) {\n    dest.set(data, offset);\n  } else if (typeof data === \"string\") {\n    for (let i = 0, ii = data.length; i < ii; i++) {\n      dest[offset++] = data.charCodeAt(i) & 0xff;\n    }\n  } else {\n    for (const num of data) {\n      dest[offset++] = num & 0xff;\n    }\n  }\n}\nconst OTF_HEADER_SIZE = 12;\nconst OTF_TABLE_ENTRY_SIZE = 16;\nclass OpenTypeFileBuilder {\n  constructor(sfnt) {\n    this.sfnt = sfnt;\n    this.tables = Object.create(null);\n  }\n  static getSearchParams(entriesCount, entrySize) {\n    let maxPower2 = 1,\n      log2 = 0;\n    while ((maxPower2 ^ entriesCount) > maxPower2) {\n      maxPower2 <<= 1;\n      log2++;\n    }\n    const searchRange = maxPower2 * entrySize;\n    return {\n      range: searchRange,\n      entry: log2,\n      rangeShift: entrySize * entriesCount - searchRange\n    };\n  }\n  toArray() {\n    let sfnt = this.sfnt;\n    const tables = this.tables;\n    const tablesNames = Object.keys(tables);\n    tablesNames.sort();\n    const numTables = tablesNames.length;\n    let i, j, jj, table, tableName;\n    let offset = OTF_HEADER_SIZE + numTables * OTF_TABLE_ENTRY_SIZE;\n    const tableOffsets = [offset];\n    for (i = 0; i < numTables; i++) {\n      table = tables[tablesNames[i]];\n      const paddedLength = (table.length + 3 & ~3) >>> 0;\n      offset += paddedLength;\n      tableOffsets.push(offset);\n    }\n    const file = new Uint8Array(offset);\n    for (i = 0; i < numTables; i++) {\n      table = tables[tablesNames[i]];\n      writeData(file, tableOffsets[i], table);\n    }\n    if (sfnt === \"true\") {\n      sfnt = string32(0x00010000);\n    }\n    file[0] = sfnt.charCodeAt(0) & 0xff;\n    file[1] = sfnt.charCodeAt(1) & 0xff;\n    file[2] = sfnt.charCodeAt(2) & 0xff;\n    file[3] = sfnt.charCodeAt(3) & 0xff;\n    writeInt16(file, 4, numTables);\n    const searchParams = OpenTypeFileBuilder.getSearchParams(numTables, 16);\n    writeInt16(file, 6, searchParams.range);\n    writeInt16(file, 8, searchParams.entry);\n    writeInt16(file, 10, searchParams.rangeShift);\n    offset = OTF_HEADER_SIZE;\n    for (i = 0; i < numTables; i++) {\n      tableName = tablesNames[i];\n      file[offset] = tableName.charCodeAt(0) & 0xff;\n      file[offset + 1] = tableName.charCodeAt(1) & 0xff;\n      file[offset + 2] = tableName.charCodeAt(2) & 0xff;\n      file[offset + 3] = tableName.charCodeAt(3) & 0xff;\n      let checksum = 0;\n      for (j = tableOffsets[i], jj = tableOffsets[i + 1]; j < jj; j += 4) {\n        const quad = readUint32(file, j);\n        checksum = checksum + quad >>> 0;\n      }\n      writeInt32(file, offset + 4, checksum);\n      writeInt32(file, offset + 8, tableOffsets[i]);\n      writeInt32(file, offset + 12, tables[tableName].length);\n      offset += OTF_TABLE_ENTRY_SIZE;\n    }\n    return file;\n  }\n  addTable(tag, data) {\n    if (tag in this.tables) {\n      throw new Error(\"Table \" + tag + \" already exists\");\n    }\n    this.tables[tag] = data;\n  }\n}\n\n;// ./src/core/type1_parser.js\n\n\n\n\nconst HINTING_ENABLED = false;\nconst COMMAND_MAP = {\n  hstem: [1],\n  vstem: [3],\n  vmoveto: [4],\n  rlineto: [5],\n  hlineto: [6],\n  vlineto: [7],\n  rrcurveto: [8],\n  callsubr: [10],\n  flex: [12, 35],\n  drop: [12, 18],\n  endchar: [14],\n  rmoveto: [21],\n  hmoveto: [22],\n  vhcurveto: [30],\n  hvcurveto: [31]\n};\nclass Type1CharString {\n  constructor() {\n    this.width = 0;\n    this.lsb = 0;\n    this.flexing = false;\n    this.output = [];\n    this.stack = [];\n  }\n  convert(encoded, subrs, seacAnalysisEnabled) {\n    const count = encoded.length;\n    let error = false;\n    let wx, sbx, subrNumber;\n    for (let i = 0; i < count; i++) {\n      let value = encoded[i];\n      if (value < 32) {\n        if (value === 12) {\n          value = (value << 8) + encoded[++i];\n        }\n        switch (value) {\n          case 1:\n            if (!HINTING_ENABLED) {\n              this.stack = [];\n              break;\n            }\n            error = this.executeCommand(2, COMMAND_MAP.hstem);\n            break;\n          case 3:\n            if (!HINTING_ENABLED) {\n              this.stack = [];\n              break;\n            }\n            error = this.executeCommand(2, COMMAND_MAP.vstem);\n            break;\n          case 4:\n            if (this.flexing) {\n              if (this.stack.length < 1) {\n                error = true;\n                break;\n              }\n              const dy = this.stack.pop();\n              this.stack.push(0, dy);\n              break;\n            }\n            error = this.executeCommand(1, COMMAND_MAP.vmoveto);\n            break;\n          case 5:\n            error = this.executeCommand(2, COMMAND_MAP.rlineto);\n            break;\n          case 6:\n            error = this.executeCommand(1, COMMAND_MAP.hlineto);\n            break;\n          case 7:\n            error = this.executeCommand(1, COMMAND_MAP.vlineto);\n            break;\n          case 8:\n            error = this.executeCommand(6, COMMAND_MAP.rrcurveto);\n            break;\n          case 9:\n            this.stack = [];\n            break;\n          case 10:\n            if (this.stack.length < 1) {\n              error = true;\n              break;\n            }\n            subrNumber = this.stack.pop();\n            if (!subrs[subrNumber]) {\n              error = true;\n              break;\n            }\n            error = this.convert(subrs[subrNumber], subrs, seacAnalysisEnabled);\n            break;\n          case 11:\n            return error;\n          case 13:\n            if (this.stack.length < 2) {\n              error = true;\n              break;\n            }\n            wx = this.stack.pop();\n            sbx = this.stack.pop();\n            this.lsb = sbx;\n            this.width = wx;\n            this.stack.push(wx, sbx);\n            error = this.executeCommand(2, COMMAND_MAP.hmoveto);\n            break;\n          case 14:\n            this.output.push(COMMAND_MAP.endchar[0]);\n            break;\n          case 21:\n            if (this.flexing) {\n              break;\n            }\n            error = this.executeCommand(2, COMMAND_MAP.rmoveto);\n            break;\n          case 22:\n            if (this.flexing) {\n              this.stack.push(0);\n              break;\n            }\n            error = this.executeCommand(1, COMMAND_MAP.hmoveto);\n            break;\n          case 30:\n            error = this.executeCommand(4, COMMAND_MAP.vhcurveto);\n            break;\n          case 31:\n            error = this.executeCommand(4, COMMAND_MAP.hvcurveto);\n            break;\n          case (12 << 8) + 0:\n            this.stack = [];\n            break;\n          case (12 << 8) + 1:\n            if (!HINTING_ENABLED) {\n              this.stack = [];\n              break;\n            }\n            error = this.executeCommand(2, COMMAND_MAP.vstem);\n            break;\n          case (12 << 8) + 2:\n            if (!HINTING_ENABLED) {\n              this.stack = [];\n              break;\n            }\n            error = this.executeCommand(2, COMMAND_MAP.hstem);\n            break;\n          case (12 << 8) + 6:\n            if (seacAnalysisEnabled) {\n              const asb = this.stack.at(-5);\n              this.seac = this.stack.splice(-4, 4);\n              this.seac[0] += this.lsb - asb;\n              error = this.executeCommand(0, COMMAND_MAP.endchar);\n            } else {\n              error = this.executeCommand(4, COMMAND_MAP.endchar);\n            }\n            break;\n          case (12 << 8) + 7:\n            if (this.stack.length < 4) {\n              error = true;\n              break;\n            }\n            this.stack.pop();\n            wx = this.stack.pop();\n            const sby = this.stack.pop();\n            sbx = this.stack.pop();\n            this.lsb = sbx;\n            this.width = wx;\n            this.stack.push(wx, sbx, sby);\n            error = this.executeCommand(3, COMMAND_MAP.rmoveto);\n            break;\n          case (12 << 8) + 12:\n            if (this.stack.length < 2) {\n              error = true;\n              break;\n            }\n            const num2 = this.stack.pop();\n            const num1 = this.stack.pop();\n            this.stack.push(num1 / num2);\n            break;\n          case (12 << 8) + 16:\n            if (this.stack.length < 2) {\n              error = true;\n              break;\n            }\n            subrNumber = this.stack.pop();\n            const numArgs = this.stack.pop();\n            if (subrNumber === 0 && numArgs === 3) {\n              const flexArgs = this.stack.splice(-17, 17);\n              this.stack.push(flexArgs[2] + flexArgs[0], flexArgs[3] + flexArgs[1], flexArgs[4], flexArgs[5], flexArgs[6], flexArgs[7], flexArgs[8], flexArgs[9], flexArgs[10], flexArgs[11], flexArgs[12], flexArgs[13], flexArgs[14]);\n              error = this.executeCommand(13, COMMAND_MAP.flex, true);\n              this.flexing = false;\n              this.stack.push(flexArgs[15], flexArgs[16]);\n            } else if (subrNumber === 1 && numArgs === 0) {\n              this.flexing = true;\n            }\n            break;\n          case (12 << 8) + 17:\n            break;\n          case (12 << 8) + 33:\n            this.stack = [];\n            break;\n          default:\n            warn('Unknown type 1 charstring command of \"' + value + '\"');\n            break;\n        }\n        if (error) {\n          break;\n        }\n        continue;\n      } else if (value <= 246) {\n        value -= 139;\n      } else if (value <= 250) {\n        value = (value - 247) * 256 + encoded[++i] + 108;\n      } else if (value <= 254) {\n        value = -((value - 251) * 256) - encoded[++i] - 108;\n      } else {\n        value = (encoded[++i] & 0xff) << 24 | (encoded[++i] & 0xff) << 16 | (encoded[++i] & 0xff) << 8 | (encoded[++i] & 0xff) << 0;\n      }\n      this.stack.push(value);\n    }\n    return error;\n  }\n  executeCommand(howManyArgs, command, keepStack) {\n    const stackLength = this.stack.length;\n    if (howManyArgs > stackLength) {\n      return true;\n    }\n    const start = stackLength - howManyArgs;\n    for (let i = start; i < stackLength; i++) {\n      let value = this.stack[i];\n      if (Number.isInteger(value)) {\n        this.output.push(28, value >> 8 & 0xff, value & 0xff);\n      } else {\n        value = 65536 * value | 0;\n        this.output.push(255, value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff);\n      }\n    }\n    this.output.push(...command);\n    if (keepStack) {\n      this.stack.splice(start, howManyArgs);\n    } else {\n      this.stack.length = 0;\n    }\n    return false;\n  }\n}\nconst EEXEC_ENCRYPT_KEY = 55665;\nconst CHAR_STRS_ENCRYPT_KEY = 4330;\nfunction isHexDigit(code) {\n  return code >= 48 && code <= 57 || code >= 65 && code <= 70 || code >= 97 && code <= 102;\n}\nfunction decrypt(data, key, discardNumber) {\n  if (discardNumber >= data.length) {\n    return new Uint8Array(0);\n  }\n  const c1 = 52845,\n    c2 = 22719;\n  let r = key | 0,\n    i,\n    j;\n  for (i = 0; i < discardNumber; i++) {\n    r = (data[i] + r) * c1 + c2 & (1 << 16) - 1;\n  }\n  const count = data.length - discardNumber;\n  const decrypted = new Uint8Array(count);\n  for (i = discardNumber, j = 0; j < count; i++, j++) {\n    const value = data[i];\n    decrypted[j] = value ^ r >> 8;\n    r = (value + r) * c1 + c2 & (1 << 16) - 1;\n  }\n  return decrypted;\n}\nfunction decryptAscii(data, key, discardNumber) {\n  const c1 = 52845,\n    c2 = 22719;\n  let r = key | 0;\n  const count = data.length,\n    maybeLength = count >>> 1;\n  const decrypted = new Uint8Array(maybeLength);\n  let i, j;\n  for (i = 0, j = 0; i < count; i++) {\n    const digit1 = data[i];\n    if (!isHexDigit(digit1)) {\n      continue;\n    }\n    i++;\n    let digit2;\n    while (i < count && !isHexDigit(digit2 = data[i])) {\n      i++;\n    }\n    if (i < count) {\n      const value = parseInt(String.fromCharCode(digit1, digit2), 16);\n      decrypted[j++] = value ^ r >> 8;\n      r = (value + r) * c1 + c2 & (1 << 16) - 1;\n    }\n  }\n  return decrypted.slice(discardNumber, j);\n}\nfunction isSpecial(c) {\n  return c === 0x2f || c === 0x5b || c === 0x5d || c === 0x7b || c === 0x7d || c === 0x28 || c === 0x29;\n}\nclass Type1Parser {\n  constructor(stream, encrypted, seacAnalysisEnabled) {\n    if (encrypted) {\n      const data = stream.getBytes();\n      const isBinary = !((isHexDigit(data[0]) || isWhiteSpace(data[0])) && isHexDigit(data[1]) && isHexDigit(data[2]) && isHexDigit(data[3]) && isHexDigit(data[4]) && isHexDigit(data[5]) && isHexDigit(data[6]) && isHexDigit(data[7]));\n      stream = new Stream(isBinary ? decrypt(data, EEXEC_ENCRYPT_KEY, 4) : decryptAscii(data, EEXEC_ENCRYPT_KEY, 4));\n    }\n    this.seacAnalysisEnabled = !!seacAnalysisEnabled;\n    this.stream = stream;\n    this.nextChar();\n  }\n  readNumberArray() {\n    this.getToken();\n    const array = [];\n    while (true) {\n      const token = this.getToken();\n      if (token === null || token === \"]\" || token === \"}\") {\n        break;\n      }\n      array.push(parseFloat(token || 0));\n    }\n    return array;\n  }\n  readNumber() {\n    const token = this.getToken();\n    return parseFloat(token || 0);\n  }\n  readInt() {\n    const token = this.getToken();\n    return parseInt(token || 0, 10) | 0;\n  }\n  readBoolean() {\n    const token = this.getToken();\n    return token === \"true\" ? 1 : 0;\n  }\n  nextChar() {\n    return this.currentChar = this.stream.getByte();\n  }\n  prevChar() {\n    this.stream.skip(-2);\n    return this.currentChar = this.stream.getByte();\n  }\n  getToken() {\n    let comment = false;\n    let ch = this.currentChar;\n    while (true) {\n      if (ch === -1) {\n        return null;\n      }\n      if (comment) {\n        if (ch === 0x0a || ch === 0x0d) {\n          comment = false;\n        }\n      } else if (ch === 0x25) {\n        comment = true;\n      } else if (!isWhiteSpace(ch)) {\n        break;\n      }\n      ch = this.nextChar();\n    }\n    if (isSpecial(ch)) {\n      this.nextChar();\n      return String.fromCharCode(ch);\n    }\n    let token = \"\";\n    do {\n      token += String.fromCharCode(ch);\n      ch = this.nextChar();\n    } while (ch >= 0 && !isWhiteSpace(ch) && !isSpecial(ch));\n    return token;\n  }\n  readCharStrings(bytes, lenIV) {\n    if (lenIV === -1) {\n      return bytes;\n    }\n    return decrypt(bytes, CHAR_STRS_ENCRYPT_KEY, lenIV);\n  }\n  extractFontProgram(properties) {\n    const stream = this.stream;\n    const subrs = [],\n      charstrings = [];\n    const privateData = Object.create(null);\n    privateData.lenIV = 4;\n    const program = {\n      subrs: [],\n      charstrings: [],\n      properties: {\n        privateData\n      }\n    };\n    let token, length, data, lenIV;\n    while ((token = this.getToken()) !== null) {\n      if (token !== \"/\") {\n        continue;\n      }\n      token = this.getToken();\n      switch (token) {\n        case \"CharStrings\":\n          this.getToken();\n          this.getToken();\n          this.getToken();\n          this.getToken();\n          while (true) {\n            token = this.getToken();\n            if (token === null || token === \"end\") {\n              break;\n            }\n            if (token !== \"/\") {\n              continue;\n            }\n            const glyph = this.getToken();\n            length = this.readInt();\n            this.getToken();\n            data = length > 0 ? stream.getBytes(length) : new Uint8Array(0);\n            lenIV = program.properties.privateData.lenIV;\n            const encoded = this.readCharStrings(data, lenIV);\n            this.nextChar();\n            token = this.getToken();\n            if (token === \"noaccess\") {\n              this.getToken();\n            } else if (token === \"/\") {\n              this.prevChar();\n            }\n            charstrings.push({\n              glyph,\n              encoded\n            });\n          }\n          break;\n        case \"Subrs\":\n          this.readInt();\n          this.getToken();\n          while (this.getToken() === \"dup\") {\n            const index = this.readInt();\n            length = this.readInt();\n            this.getToken();\n            data = length > 0 ? stream.getBytes(length) : new Uint8Array(0);\n            lenIV = program.properties.privateData.lenIV;\n            const encoded = this.readCharStrings(data, lenIV);\n            this.nextChar();\n            token = this.getToken();\n            if (token === \"noaccess\") {\n              this.getToken();\n            }\n            subrs[index] = encoded;\n          }\n          break;\n        case \"BlueValues\":\n        case \"OtherBlues\":\n        case \"FamilyBlues\":\n        case \"FamilyOtherBlues\":\n          const blueArray = this.readNumberArray();\n          if (blueArray.length > 0 && blueArray.length % 2 === 0 && HINTING_ENABLED) {\n            program.properties.privateData[token] = blueArray;\n          }\n          break;\n        case \"StemSnapH\":\n        case \"StemSnapV\":\n          program.properties.privateData[token] = this.readNumberArray();\n          break;\n        case \"StdHW\":\n        case \"StdVW\":\n          program.properties.privateData[token] = this.readNumberArray()[0];\n          break;\n        case \"BlueShift\":\n        case \"lenIV\":\n        case \"BlueFuzz\":\n        case \"BlueScale\":\n        case \"LanguageGroup\":\n          program.properties.privateData[token] = this.readNumber();\n          break;\n        case \"ExpansionFactor\":\n          program.properties.privateData[token] = this.readNumber() || 0.06;\n          break;\n        case \"ForceBold\":\n          program.properties.privateData[token] = this.readBoolean();\n          break;\n      }\n    }\n    for (const {\n      encoded,\n      glyph\n    } of charstrings) {\n      const charString = new Type1CharString();\n      const error = charString.convert(encoded, subrs, this.seacAnalysisEnabled);\n      let output = charString.output;\n      if (error) {\n        output = [14];\n      }\n      const charStringObject = {\n        glyphName: glyph,\n        charstring: output,\n        width: charString.width,\n        lsb: charString.lsb,\n        seac: charString.seac\n      };\n      if (glyph === \".notdef\") {\n        program.charstrings.unshift(charStringObject);\n      } else {\n        program.charstrings.push(charStringObject);\n      }\n      if (properties.builtInEncoding) {\n        const index = properties.builtInEncoding.indexOf(glyph);\n        if (index > -1 && properties.widths[index] === undefined && index >= properties.firstChar && index <= properties.lastChar) {\n          properties.widths[index] = charString.width;\n        }\n      }\n    }\n    return program;\n  }\n  extractFontHeader(properties) {\n    let token;\n    while ((token = this.getToken()) !== null) {\n      if (token !== \"/\") {\n        continue;\n      }\n      token = this.getToken();\n      switch (token) {\n        case \"FontMatrix\":\n          const matrix = this.readNumberArray();\n          properties.fontMatrix = matrix;\n          break;\n        case \"Encoding\":\n          const encodingArg = this.getToken();\n          let encoding;\n          if (!/^\\d+$/.test(encodingArg)) {\n            encoding = getEncoding(encodingArg);\n          } else {\n            encoding = [];\n            const size = parseInt(encodingArg, 10) | 0;\n            this.getToken();\n            for (let j = 0; j < size; j++) {\n              token = this.getToken();\n              while (token !== \"dup\" && token !== \"def\") {\n                token = this.getToken();\n                if (token === null) {\n                  return;\n                }\n              }\n              if (token === \"def\") {\n                break;\n              }\n              const index = this.readInt();\n              this.getToken();\n              const glyph = this.getToken();\n              encoding[index] = glyph;\n              this.getToken();\n            }\n          }\n          properties.builtInEncoding = encoding;\n          break;\n        case \"FontBBox\":\n          const fontBBox = this.readNumberArray();\n          properties.ascent = Math.max(fontBBox[3], fontBBox[1]);\n          properties.descent = Math.min(fontBBox[1], fontBBox[3]);\n          properties.ascentScaled = true;\n          break;\n      }\n    }\n  }\n}\n\n;// ./src/core/type1_font.js\n\n\n\n\n\n\nfunction findBlock(streamBytes, signature, startIndex) {\n  const streamBytesLength = streamBytes.length;\n  const signatureLength = signature.length;\n  const scanLength = streamBytesLength - signatureLength;\n  let i = startIndex,\n    found = false;\n  while (i < scanLength) {\n    let j = 0;\n    while (j < signatureLength && streamBytes[i + j] === signature[j]) {\n      j++;\n    }\n    if (j >= signatureLength) {\n      i += j;\n      while (i < streamBytesLength && isWhiteSpace(streamBytes[i])) {\n        i++;\n      }\n      found = true;\n      break;\n    }\n    i++;\n  }\n  return {\n    found,\n    length: i\n  };\n}\nfunction getHeaderBlock(stream, suggestedLength) {\n  const EEXEC_SIGNATURE = [0x65, 0x65, 0x78, 0x65, 0x63];\n  const streamStartPos = stream.pos;\n  let headerBytes, headerBytesLength, block;\n  try {\n    headerBytes = stream.getBytes(suggestedLength);\n    headerBytesLength = headerBytes.length;\n  } catch {}\n  if (headerBytesLength === suggestedLength) {\n    block = findBlock(headerBytes, EEXEC_SIGNATURE, suggestedLength - 2 * EEXEC_SIGNATURE.length);\n    if (block.found && block.length === suggestedLength) {\n      return {\n        stream: new Stream(headerBytes),\n        length: suggestedLength\n      };\n    }\n  }\n  warn('Invalid \"Length1\" property in Type1 font -- trying to recover.');\n  stream.pos = streamStartPos;\n  const SCAN_BLOCK_LENGTH = 2048;\n  let actualLength;\n  while (true) {\n    const scanBytes = stream.peekBytes(SCAN_BLOCK_LENGTH);\n    block = findBlock(scanBytes, EEXEC_SIGNATURE, 0);\n    if (block.length === 0) {\n      break;\n    }\n    stream.pos += block.length;\n    if (block.found) {\n      actualLength = stream.pos - streamStartPos;\n      break;\n    }\n  }\n  stream.pos = streamStartPos;\n  if (actualLength) {\n    return {\n      stream: new Stream(stream.getBytes(actualLength)),\n      length: actualLength\n    };\n  }\n  warn('Unable to recover \"Length1\" property in Type1 font -- using as is.');\n  return {\n    stream: new Stream(stream.getBytes(suggestedLength)),\n    length: suggestedLength\n  };\n}\nfunction getEexecBlock(stream, suggestedLength) {\n  const eexecBytes = stream.getBytes();\n  if (eexecBytes.length === 0) {\n    throw new FormatError(\"getEexecBlock - no font program found.\");\n  }\n  return {\n    stream: new Stream(eexecBytes),\n    length: eexecBytes.length\n  };\n}\nclass Type1Font {\n  constructor(name, file, properties) {\n    const PFB_HEADER_SIZE = 6;\n    let headerBlockLength = properties.length1;\n    let eexecBlockLength = properties.length2;\n    let pfbHeader = file.peekBytes(PFB_HEADER_SIZE);\n    const pfbHeaderPresent = pfbHeader[0] === 0x80 && pfbHeader[1] === 0x01;\n    if (pfbHeaderPresent) {\n      file.skip(PFB_HEADER_SIZE);\n      headerBlockLength = pfbHeader[5] << 24 | pfbHeader[4] << 16 | pfbHeader[3] << 8 | pfbHeader[2];\n    }\n    const headerBlock = getHeaderBlock(file, headerBlockLength);\n    const headerBlockParser = new Type1Parser(headerBlock.stream, false, SEAC_ANALYSIS_ENABLED);\n    headerBlockParser.extractFontHeader(properties);\n    if (pfbHeaderPresent) {\n      pfbHeader = file.getBytes(PFB_HEADER_SIZE);\n      eexecBlockLength = pfbHeader[5] << 24 | pfbHeader[4] << 16 | pfbHeader[3] << 8 | pfbHeader[2];\n    }\n    const eexecBlock = getEexecBlock(file, eexecBlockLength);\n    const eexecBlockParser = new Type1Parser(eexecBlock.stream, true, SEAC_ANALYSIS_ENABLED);\n    const data = eexecBlockParser.extractFontProgram(properties);\n    for (const key in data.properties) {\n      properties[key] = data.properties[key];\n    }\n    const charstrings = data.charstrings;\n    const type2Charstrings = this.getType2Charstrings(charstrings);\n    const subrs = this.getType2Subrs(data.subrs);\n    this.charstrings = charstrings;\n    this.data = this.wrap(name, type2Charstrings, this.charstrings, subrs, properties);\n    this.seacs = this.getSeacs(data.charstrings);\n  }\n  get numGlyphs() {\n    return this.charstrings.length + 1;\n  }\n  getCharset() {\n    const charset = [\".notdef\"];\n    for (const {\n      glyphName\n    } of this.charstrings) {\n      charset.push(glyphName);\n    }\n    return charset;\n  }\n  getGlyphMapping(properties) {\n    const charstrings = this.charstrings;\n    if (properties.composite) {\n      const charCodeToGlyphId = Object.create(null);\n      for (let glyphId = 0, charstringsLen = charstrings.length; glyphId < charstringsLen; glyphId++) {\n        const charCode = properties.cMap.charCodeOf(glyphId);\n        charCodeToGlyphId[charCode] = glyphId + 1;\n      }\n      return charCodeToGlyphId;\n    }\n    const glyphNames = [\".notdef\"];\n    let builtInEncoding, glyphId;\n    for (glyphId = 0; glyphId < charstrings.length; glyphId++) {\n      glyphNames.push(charstrings[glyphId].glyphName);\n    }\n    const encoding = properties.builtInEncoding;\n    if (encoding) {\n      builtInEncoding = Object.create(null);\n      for (const charCode in encoding) {\n        glyphId = glyphNames.indexOf(encoding[charCode]);\n        if (glyphId >= 0) {\n          builtInEncoding[charCode] = glyphId;\n        }\n      }\n    }\n    return type1FontGlyphMapping(properties, builtInEncoding, glyphNames);\n  }\n  hasGlyphId(id) {\n    if (id < 0 || id >= this.numGlyphs) {\n      return false;\n    }\n    if (id === 0) {\n      return true;\n    }\n    const glyph = this.charstrings[id - 1];\n    return glyph.charstring.length > 0;\n  }\n  getSeacs(charstrings) {\n    const seacMap = [];\n    for (let i = 0, ii = charstrings.length; i < ii; i++) {\n      const charstring = charstrings[i];\n      if (charstring.seac) {\n        seacMap[i + 1] = charstring.seac;\n      }\n    }\n    return seacMap;\n  }\n  getType2Charstrings(type1Charstrings) {\n    const type2Charstrings = [];\n    for (const type1Charstring of type1Charstrings) {\n      type2Charstrings.push(type1Charstring.charstring);\n    }\n    return type2Charstrings;\n  }\n  getType2Subrs(type1Subrs) {\n    let bias = 0;\n    const count = type1Subrs.length;\n    if (count < 1133) {\n      bias = 107;\n    } else if (count < 33769) {\n      bias = 1131;\n    } else {\n      bias = 32768;\n    }\n    const type2Subrs = [];\n    let i;\n    for (i = 0; i < bias; i++) {\n      type2Subrs.push([0x0b]);\n    }\n    for (i = 0; i < count; i++) {\n      type2Subrs.push(type1Subrs[i]);\n    }\n    return type2Subrs;\n  }\n  wrap(name, glyphs, charstrings, subrs, properties) {\n    const cff = new CFF();\n    cff.header = new CFFHeader(1, 0, 4, 4);\n    cff.names = [name];\n    const topDict = new CFFTopDict();\n    topDict.setByName(\"version\", 391);\n    topDict.setByName(\"Notice\", 392);\n    topDict.setByName(\"FullName\", 393);\n    topDict.setByName(\"FamilyName\", 394);\n    topDict.setByName(\"Weight\", 395);\n    topDict.setByName(\"Encoding\", null);\n    topDict.setByName(\"FontMatrix\", properties.fontMatrix);\n    topDict.setByName(\"FontBBox\", properties.bbox);\n    topDict.setByName(\"charset\", null);\n    topDict.setByName(\"CharStrings\", null);\n    topDict.setByName(\"Private\", null);\n    cff.topDict = topDict;\n    const strings = new CFFStrings();\n    strings.add(\"Version 0.11\");\n    strings.add(\"See original notice\");\n    strings.add(name);\n    strings.add(name);\n    strings.add(\"Medium\");\n    cff.strings = strings;\n    cff.globalSubrIndex = new CFFIndex();\n    const count = glyphs.length;\n    const charsetArray = [\".notdef\"];\n    let i, ii;\n    for (i = 0; i < count; i++) {\n      const glyphName = charstrings[i].glyphName;\n      const index = CFFStandardStrings.indexOf(glyphName);\n      if (index === -1) {\n        strings.add(glyphName);\n      }\n      charsetArray.push(glyphName);\n    }\n    cff.charset = new CFFCharset(false, 0, charsetArray);\n    const charStringsIndex = new CFFIndex();\n    charStringsIndex.add([0x8b, 0x0e]);\n    for (i = 0; i < count; i++) {\n      charStringsIndex.add(glyphs[i]);\n    }\n    cff.charStrings = charStringsIndex;\n    const privateDict = new CFFPrivateDict();\n    privateDict.setByName(\"Subrs\", null);\n    const fields = [\"BlueValues\", \"OtherBlues\", \"FamilyBlues\", \"FamilyOtherBlues\", \"StemSnapH\", \"StemSnapV\", \"BlueShift\", \"BlueFuzz\", \"BlueScale\", \"LanguageGroup\", \"ExpansionFactor\", \"ForceBold\", \"StdHW\", \"StdVW\"];\n    for (i = 0, ii = fields.length; i < ii; i++) {\n      const field = fields[i];\n      if (!(field in properties.privateData)) {\n        continue;\n      }\n      const value = properties.privateData[field];\n      if (Array.isArray(value)) {\n        for (let j = value.length - 1; j > 0; j--) {\n          value[j] -= value[j - 1];\n        }\n      }\n      privateDict.setByName(field, value);\n    }\n    cff.topDict.privateDict = privateDict;\n    const subrIndex = new CFFIndex();\n    for (i = 0, ii = subrs.length; i < ii; i++) {\n      subrIndex.add(subrs[i]);\n    }\n    privateDict.subrsIndex = subrIndex;\n    const compiler = new CFFCompiler(cff);\n    return compiler.compile();\n  }\n}\n\n;// ./src/core/fonts.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst PRIVATE_USE_AREAS = [[0xe000, 0xf8ff], [0x100000, 0x10fffd]];\nconst PDF_GLYPH_SPACE_UNITS = 1000;\nconst EXPORT_DATA_PROPERTIES = [\"ascent\", \"bbox\", \"black\", \"bold\", \"charProcOperatorList\", \"composite\", \"cssFontInfo\", \"data\", \"defaultVMetrics\", \"defaultWidth\", \"descent\", \"fallbackName\", \"fontMatrix\", \"isInvalidPDFjsFont\", \"isType3Font\", \"italic\", \"loadedName\", \"mimetype\", \"missingFile\", \"name\", \"remeasure\", \"subtype\", \"systemFontInfo\", \"type\", \"vertical\"];\nconst EXPORT_DATA_EXTRA_PROPERTIES = [\"cMap\", \"defaultEncoding\", \"differences\", \"isMonospace\", \"isSerifFont\", \"isSymbolicFont\", \"seacMap\", \"toFontChar\", \"toUnicode\", \"vmetrics\", \"widths\"];\nfunction adjustWidths(properties) {\n  if (!properties.fontMatrix) {\n    return;\n  }\n  if (properties.fontMatrix[0] === FONT_IDENTITY_MATRIX[0]) {\n    return;\n  }\n  const scale = 0.001 / properties.fontMatrix[0];\n  const glyphsWidths = properties.widths;\n  for (const glyph in glyphsWidths) {\n    glyphsWidths[glyph] *= scale;\n  }\n  properties.defaultWidth *= scale;\n}\nfunction adjustTrueTypeToUnicode(properties, isSymbolicFont, nameRecords) {\n  if (properties.isInternalFont) {\n    return;\n  }\n  if (properties.hasIncludedToUnicodeMap) {\n    return;\n  }\n  if (properties.hasEncoding) {\n    return;\n  }\n  if (properties.toUnicode instanceof IdentityToUnicodeMap) {\n    return;\n  }\n  if (!isSymbolicFont) {\n    return;\n  }\n  if (nameRecords.length === 0) {\n    return;\n  }\n  if (properties.defaultEncoding === WinAnsiEncoding) {\n    return;\n  }\n  for (const r of nameRecords) {\n    if (!isWinNameRecord(r)) {\n      return;\n    }\n  }\n  const encoding = WinAnsiEncoding;\n  const toUnicode = [],\n    glyphsUnicodeMap = getGlyphsUnicode();\n  for (const charCode in encoding) {\n    const glyphName = encoding[charCode];\n    if (glyphName === \"\") {\n      continue;\n    }\n    const unicode = glyphsUnicodeMap[glyphName];\n    if (unicode === undefined) {\n      continue;\n    }\n    toUnicode[charCode] = String.fromCharCode(unicode);\n  }\n  if (toUnicode.length > 0) {\n    properties.toUnicode.amend(toUnicode);\n  }\n}\nfunction adjustType1ToUnicode(properties, builtInEncoding) {\n  if (properties.isInternalFont) {\n    return;\n  }\n  if (properties.hasIncludedToUnicodeMap) {\n    return;\n  }\n  if (builtInEncoding === properties.defaultEncoding) {\n    return;\n  }\n  if (properties.toUnicode instanceof IdentityToUnicodeMap) {\n    return;\n  }\n  const toUnicode = [],\n    glyphsUnicodeMap = getGlyphsUnicode();\n  for (const charCode in builtInEncoding) {\n    if (properties.hasEncoding) {\n      if (properties.baseEncodingName || properties.differences[charCode] !== undefined) {\n        continue;\n      }\n    }\n    const glyphName = builtInEncoding[charCode];\n    const unicode = getUnicodeForGlyph(glyphName, glyphsUnicodeMap);\n    if (unicode !== -1) {\n      toUnicode[charCode] = String.fromCharCode(unicode);\n    }\n  }\n  if (toUnicode.length > 0) {\n    properties.toUnicode.amend(toUnicode);\n  }\n}\nfunction amendFallbackToUnicode(properties) {\n  if (!properties.fallbackToUnicode) {\n    return;\n  }\n  if (properties.toUnicode instanceof IdentityToUnicodeMap) {\n    return;\n  }\n  const toUnicode = [];\n  for (const charCode in properties.fallbackToUnicode) {\n    if (properties.toUnicode.has(charCode)) {\n      continue;\n    }\n    toUnicode[charCode] = properties.fallbackToUnicode[charCode];\n  }\n  if (toUnicode.length > 0) {\n    properties.toUnicode.amend(toUnicode);\n  }\n}\nclass fonts_Glyph {\n  constructor(originalCharCode, fontChar, unicode, accent, width, vmetric, operatorListId, isSpace, isInFont) {\n    this.originalCharCode = originalCharCode;\n    this.fontChar = fontChar;\n    this.unicode = unicode;\n    this.accent = accent;\n    this.width = width;\n    this.vmetric = vmetric;\n    this.operatorListId = operatorListId;\n    this.isSpace = isSpace;\n    this.isInFont = isInFont;\n  }\n  get category() {\n    return shadow(this, \"category\", getCharUnicodeCategory(this.unicode), true);\n  }\n}\nfunction int16(b0, b1) {\n  return (b0 << 8) + b1;\n}\nfunction writeSignedInt16(bytes, index, value) {\n  bytes[index + 1] = value;\n  bytes[index] = value >>> 8;\n}\nfunction signedInt16(b0, b1) {\n  const value = (b0 << 8) + b1;\n  return value & 1 << 15 ? value - 0x10000 : value;\n}\nfunction writeUint32(bytes, index, value) {\n  bytes[index + 3] = value & 0xff;\n  bytes[index + 2] = value >>> 8;\n  bytes[index + 1] = value >>> 16;\n  bytes[index] = value >>> 24;\n}\nfunction int32(b0, b1, b2, b3) {\n  return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3;\n}\nfunction string16(value) {\n  return String.fromCharCode(value >> 8 & 0xff, value & 0xff);\n}\nfunction safeString16(value) {\n  if (value > 0x7fff) {\n    value = 0x7fff;\n  } else if (value < -0x8000) {\n    value = -0x8000;\n  }\n  return String.fromCharCode(value >> 8 & 0xff, value & 0xff);\n}\nfunction isTrueTypeFile(file) {\n  const header = file.peekBytes(4);\n  return readUint32(header, 0) === 0x00010000 || bytesToString(header) === \"true\";\n}\nfunction isTrueTypeCollectionFile(file) {\n  const header = file.peekBytes(4);\n  return bytesToString(header) === \"ttcf\";\n}\nfunction isOpenTypeFile(file) {\n  const header = file.peekBytes(4);\n  return bytesToString(header) === \"OTTO\";\n}\nfunction isType1File(file) {\n  const header = file.peekBytes(2);\n  if (header[0] === 0x25 && header[1] === 0x21) {\n    return true;\n  }\n  if (header[0] === 0x80 && header[1] === 0x01) {\n    return true;\n  }\n  return false;\n}\nfunction isCFFFile(file) {\n  const header = file.peekBytes(4);\n  if (header[0] >= 1 && header[3] >= 1 && header[3] <= 4) {\n    return true;\n  }\n  return false;\n}\nfunction getFontFileType(file, {\n  type,\n  subtype,\n  composite\n}) {\n  let fileType, fileSubtype;\n  if (isTrueTypeFile(file) || isTrueTypeCollectionFile(file)) {\n    fileType = composite ? \"CIDFontType2\" : \"TrueType\";\n  } else if (isOpenTypeFile(file)) {\n    fileType = composite ? \"CIDFontType2\" : \"OpenType\";\n  } else if (isType1File(file)) {\n    if (composite) {\n      fileType = \"CIDFontType0\";\n    } else {\n      fileType = type === \"MMType1\" ? \"MMType1\" : \"Type1\";\n    }\n  } else if (isCFFFile(file)) {\n    if (composite) {\n      fileType = \"CIDFontType0\";\n      fileSubtype = \"CIDFontType0C\";\n    } else {\n      fileType = type === \"MMType1\" ? \"MMType1\" : \"Type1\";\n      fileSubtype = \"Type1C\";\n    }\n  } else {\n    warn(\"getFontFileType: Unable to detect correct font file Type/Subtype.\");\n    fileType = type;\n    fileSubtype = subtype;\n  }\n  return [fileType, fileSubtype];\n}\nfunction applyStandardFontGlyphMap(map, glyphMap) {\n  for (const charCode in glyphMap) {\n    map[+charCode] = glyphMap[charCode];\n  }\n}\nfunction buildToFontChar(encoding, glyphsUnicodeMap, differences) {\n  const toFontChar = [];\n  let unicode;\n  for (let i = 0, ii = encoding.length; i < ii; i++) {\n    unicode = getUnicodeForGlyph(encoding[i], glyphsUnicodeMap);\n    if (unicode !== -1) {\n      toFontChar[i] = unicode;\n    }\n  }\n  for (const charCode in differences) {\n    unicode = getUnicodeForGlyph(differences[charCode], glyphsUnicodeMap);\n    if (unicode !== -1) {\n      toFontChar[+charCode] = unicode;\n    }\n  }\n  return toFontChar;\n}\nfunction isMacNameRecord(r) {\n  return r.platform === 1 && r.encoding === 0 && r.language === 0;\n}\nfunction isWinNameRecord(r) {\n  return r.platform === 3 && r.encoding === 1 && r.language === 0x409;\n}\nfunction convertCidString(charCode, cid, shouldThrow = false) {\n  switch (cid.length) {\n    case 1:\n      return cid.charCodeAt(0);\n    case 2:\n      return cid.charCodeAt(0) << 8 | cid.charCodeAt(1);\n  }\n  const msg = `Unsupported CID string (charCode ${charCode}): \"${cid}\".`;\n  if (shouldThrow) {\n    throw new FormatError(msg);\n  }\n  warn(msg);\n  return cid;\n}\nfunction adjustMapping(charCodeToGlyphId, hasGlyph, newGlyphZeroId, toUnicode) {\n  const newMap = Object.create(null);\n  const toUnicodeExtraMap = new Map();\n  const toFontChar = [];\n  const usedGlyphIds = new Set();\n  let privateUseAreaIndex = 0;\n  const privateUseOffetStart = PRIVATE_USE_AREAS[privateUseAreaIndex][0];\n  let nextAvailableFontCharCode = privateUseOffetStart;\n  let privateUseOffetEnd = PRIVATE_USE_AREAS[privateUseAreaIndex][1];\n  const isInPrivateArea = code => PRIVATE_USE_AREAS[0][0] <= code && code <= PRIVATE_USE_AREAS[0][1] || PRIVATE_USE_AREAS[1][0] <= code && code <= PRIVATE_USE_AREAS[1][1];\n  for (let originalCharCode in charCodeToGlyphId) {\n    originalCharCode |= 0;\n    let glyphId = charCodeToGlyphId[originalCharCode];\n    if (!hasGlyph(glyphId)) {\n      continue;\n    }\n    if (nextAvailableFontCharCode > privateUseOffetEnd) {\n      privateUseAreaIndex++;\n      if (privateUseAreaIndex >= PRIVATE_USE_AREAS.length) {\n        warn(\"Ran out of space in font private use area.\");\n        break;\n      }\n      nextAvailableFontCharCode = PRIVATE_USE_AREAS[privateUseAreaIndex][0];\n      privateUseOffetEnd = PRIVATE_USE_AREAS[privateUseAreaIndex][1];\n    }\n    const fontCharCode = nextAvailableFontCharCode++;\n    if (glyphId === 0) {\n      glyphId = newGlyphZeroId;\n    }\n    let unicode = toUnicode.get(originalCharCode);\n    if (typeof unicode === \"string\") {\n      unicode = unicode.codePointAt(0);\n    }\n    if (unicode && !isInPrivateArea(unicode) && !usedGlyphIds.has(glyphId)) {\n      toUnicodeExtraMap.set(unicode, glyphId);\n      usedGlyphIds.add(glyphId);\n    }\n    newMap[fontCharCode] = glyphId;\n    toFontChar[originalCharCode] = fontCharCode;\n  }\n  return {\n    toFontChar,\n    charCodeToGlyphId: newMap,\n    toUnicodeExtraMap,\n    nextAvailableFontCharCode\n  };\n}\nfunction getRanges(glyphs, toUnicodeExtraMap, numGlyphs) {\n  const codes = [];\n  for (const charCode in glyphs) {\n    if (glyphs[charCode] >= numGlyphs) {\n      continue;\n    }\n    codes.push({\n      fontCharCode: charCode | 0,\n      glyphId: glyphs[charCode]\n    });\n  }\n  if (toUnicodeExtraMap) {\n    for (const [unicode, glyphId] of toUnicodeExtraMap) {\n      if (glyphId >= numGlyphs) {\n        continue;\n      }\n      codes.push({\n        fontCharCode: unicode,\n        glyphId\n      });\n    }\n  }\n  if (codes.length === 0) {\n    codes.push({\n      fontCharCode: 0,\n      glyphId: 0\n    });\n  }\n  codes.sort(function fontGetRangesSort(a, b) {\n    return a.fontCharCode - b.fontCharCode;\n  });\n  const ranges = [];\n  const length = codes.length;\n  for (let n = 0; n < length;) {\n    const start = codes[n].fontCharCode;\n    const codeIndices = [codes[n].glyphId];\n    ++n;\n    let end = start;\n    while (n < length && end + 1 === codes[n].fontCharCode) {\n      codeIndices.push(codes[n].glyphId);\n      ++end;\n      ++n;\n      if (end === 0xffff) {\n        break;\n      }\n    }\n    ranges.push([start, end, codeIndices]);\n  }\n  return ranges;\n}\nfunction createCmapTable(glyphs, toUnicodeExtraMap, numGlyphs) {\n  const ranges = getRanges(glyphs, toUnicodeExtraMap, numGlyphs);\n  const numTables = ranges.at(-1)[1] > 0xffff ? 2 : 1;\n  let cmap = \"\\x00\\x00\" + string16(numTables) + \"\\x00\\x03\" + \"\\x00\\x01\" + string32(4 + numTables * 8);\n  let i, ii, j, jj;\n  for (i = ranges.length - 1; i >= 0; --i) {\n    if (ranges[i][0] <= 0xffff) {\n      break;\n    }\n  }\n  const bmpLength = i + 1;\n  if (ranges[i][0] < 0xffff && ranges[i][1] === 0xffff) {\n    ranges[i][1] = 0xfffe;\n  }\n  const trailingRangesCount = ranges[i][1] < 0xffff ? 1 : 0;\n  const segCount = bmpLength + trailingRangesCount;\n  const searchParams = OpenTypeFileBuilder.getSearchParams(segCount, 2);\n  let startCount = \"\";\n  let endCount = \"\";\n  let idDeltas = \"\";\n  let idRangeOffsets = \"\";\n  let glyphsIds = \"\";\n  let bias = 0;\n  let range, start, end, codes;\n  for (i = 0, ii = bmpLength; i < ii; i++) {\n    range = ranges[i];\n    start = range[0];\n    end = range[1];\n    startCount += string16(start);\n    endCount += string16(end);\n    codes = range[2];\n    let contiguous = true;\n    for (j = 1, jj = codes.length; j < jj; ++j) {\n      if (codes[j] !== codes[j - 1] + 1) {\n        contiguous = false;\n        break;\n      }\n    }\n    if (!contiguous) {\n      const offset = (segCount - i) * 2 + bias * 2;\n      bias += end - start + 1;\n      idDeltas += string16(0);\n      idRangeOffsets += string16(offset);\n      for (j = 0, jj = codes.length; j < jj; ++j) {\n        glyphsIds += string16(codes[j]);\n      }\n    } else {\n      const startCode = codes[0];\n      idDeltas += string16(startCode - start & 0xffff);\n      idRangeOffsets += string16(0);\n    }\n  }\n  if (trailingRangesCount > 0) {\n    endCount += \"\\xFF\\xFF\";\n    startCount += \"\\xFF\\xFF\";\n    idDeltas += \"\\x00\\x01\";\n    idRangeOffsets += \"\\x00\\x00\";\n  }\n  const format314 = \"\\x00\\x00\" + string16(2 * segCount) + string16(searchParams.range) + string16(searchParams.entry) + string16(searchParams.rangeShift) + endCount + \"\\x00\\x00\" + startCount + idDeltas + idRangeOffsets + glyphsIds;\n  let format31012 = \"\";\n  let header31012 = \"\";\n  if (numTables > 1) {\n    cmap += \"\\x00\\x03\" + \"\\x00\\x0A\" + string32(4 + numTables * 8 + 4 + format314.length);\n    format31012 = \"\";\n    for (i = 0, ii = ranges.length; i < ii; i++) {\n      range = ranges[i];\n      start = range[0];\n      codes = range[2];\n      let code = codes[0];\n      for (j = 1, jj = codes.length; j < jj; ++j) {\n        if (codes[j] !== codes[j - 1] + 1) {\n          end = range[0] + j - 1;\n          format31012 += string32(start) + string32(end) + string32(code);\n          start = end + 1;\n          code = codes[j];\n        }\n      }\n      format31012 += string32(start) + string32(range[1]) + string32(code);\n    }\n    header31012 = \"\\x00\\x0C\" + \"\\x00\\x00\" + string32(format31012.length + 16) + \"\\x00\\x00\\x00\\x00\" + string32(format31012.length / 12);\n  }\n  return cmap + \"\\x00\\x04\" + string16(format314.length + 4) + format314 + header31012 + format31012;\n}\nfunction validateOS2Table(os2, file) {\n  file.pos = (file.start || 0) + os2.offset;\n  const version = file.getUint16();\n  file.skip(60);\n  const selection = file.getUint16();\n  if (version < 4 && selection & 0x0300) {\n    return false;\n  }\n  const firstChar = file.getUint16();\n  const lastChar = file.getUint16();\n  if (firstChar > lastChar) {\n    return false;\n  }\n  file.skip(6);\n  const usWinAscent = file.getUint16();\n  if (usWinAscent === 0) {\n    return false;\n  }\n  os2.data[8] = os2.data[9] = 0;\n  return true;\n}\nfunction createOS2Table(properties, charstrings, override) {\n  override ||= {\n    unitsPerEm: 0,\n    yMax: 0,\n    yMin: 0,\n    ascent: 0,\n    descent: 0\n  };\n  let ulUnicodeRange1 = 0;\n  let ulUnicodeRange2 = 0;\n  let ulUnicodeRange3 = 0;\n  let ulUnicodeRange4 = 0;\n  let firstCharIndex = null;\n  let lastCharIndex = 0;\n  let position = -1;\n  if (charstrings) {\n    for (let code in charstrings) {\n      code |= 0;\n      if (firstCharIndex > code || !firstCharIndex) {\n        firstCharIndex = code;\n      }\n      if (lastCharIndex < code) {\n        lastCharIndex = code;\n      }\n      position = getUnicodeRangeFor(code, position);\n      if (position < 32) {\n        ulUnicodeRange1 |= 1 << position;\n      } else if (position < 64) {\n        ulUnicodeRange2 |= 1 << position - 32;\n      } else if (position < 96) {\n        ulUnicodeRange3 |= 1 << position - 64;\n      } else if (position < 123) {\n        ulUnicodeRange4 |= 1 << position - 96;\n      } else {\n        throw new FormatError(\"Unicode ranges Bits > 123 are reserved for internal usage\");\n      }\n    }\n    if (lastCharIndex > 0xffff) {\n      lastCharIndex = 0xffff;\n    }\n  } else {\n    firstCharIndex = 0;\n    lastCharIndex = 255;\n  }\n  const bbox = properties.bbox || [0, 0, 0, 0];\n  const unitsPerEm = override.unitsPerEm || 1 / (properties.fontMatrix || FONT_IDENTITY_MATRIX)[0];\n  const scale = properties.ascentScaled ? 1.0 : unitsPerEm / PDF_GLYPH_SPACE_UNITS;\n  const typoAscent = override.ascent || Math.round(scale * (properties.ascent || bbox[3]));\n  let typoDescent = override.descent || Math.round(scale * (properties.descent || bbox[1]));\n  if (typoDescent > 0 && properties.descent > 0 && bbox[1] < 0) {\n    typoDescent = -typoDescent;\n  }\n  const winAscent = override.yMax || typoAscent;\n  const winDescent = -override.yMin || -typoDescent;\n  return \"\\x00\\x03\" + \"\\x02\\x24\" + \"\\x01\\xF4\" + \"\\x00\\x05\" + \"\\x00\\x00\" + \"\\x02\\x8A\" + \"\\x02\\xBB\" + \"\\x00\\x00\" + \"\\x00\\x8C\" + \"\\x02\\x8A\" + \"\\x02\\xBB\" + \"\\x00\\x00\" + \"\\x01\\xDF\" + \"\\x00\\x31\" + \"\\x01\\x02\" + \"\\x00\\x00\" + \"\\x00\\x00\\x06\" + String.fromCharCode(properties.fixedPitch ? 0x09 : 0x00) + \"\\x00\\x00\\x00\\x00\\x00\\x00\" + string32(ulUnicodeRange1) + string32(ulUnicodeRange2) + string32(ulUnicodeRange3) + string32(ulUnicodeRange4) + \"\\x2A\\x32\\x31\\x2A\" + string16(properties.italicAngle ? 1 : 0) + string16(firstCharIndex || properties.firstChar) + string16(lastCharIndex || properties.lastChar) + string16(typoAscent) + string16(typoDescent) + \"\\x00\\x64\" + string16(winAscent) + string16(winDescent) + \"\\x00\\x00\\x00\\x00\" + \"\\x00\\x00\\x00\\x00\" + string16(properties.xHeight) + string16(properties.capHeight) + string16(0) + string16(firstCharIndex || properties.firstChar) + \"\\x00\\x03\";\n}\nfunction createPostTable(properties) {\n  const angle = Math.floor(properties.italicAngle * 2 ** 16);\n  return \"\\x00\\x03\\x00\\x00\" + string32(angle) + \"\\x00\\x00\" + \"\\x00\\x00\" + string32(properties.fixedPitch ? 1 : 0) + \"\\x00\\x00\\x00\\x00\" + \"\\x00\\x00\\x00\\x00\" + \"\\x00\\x00\\x00\\x00\" + \"\\x00\\x00\\x00\\x00\";\n}\nfunction createPostscriptName(name) {\n  return name.replaceAll(/[^\\x21-\\x7E]|[[\\](){}<>/%]/g, \"\").slice(0, 63);\n}\nfunction createNameTable(name, proto) {\n  if (!proto) {\n    proto = [[], []];\n  }\n  const strings = [proto[0][0] || \"Original licence\", proto[0][1] || name, proto[0][2] || \"Unknown\", proto[0][3] || \"uniqueID\", proto[0][4] || name, proto[0][5] || \"Version 0.11\", proto[0][6] || createPostscriptName(name), proto[0][7] || \"Unknown\", proto[0][8] || \"Unknown\", proto[0][9] || \"Unknown\"];\n  const stringsUnicode = [];\n  let i, ii, j, jj, str;\n  for (i = 0, ii = strings.length; i < ii; i++) {\n    str = proto[1][i] || strings[i];\n    const strBufUnicode = [];\n    for (j = 0, jj = str.length; j < jj; j++) {\n      strBufUnicode.push(string16(str.charCodeAt(j)));\n    }\n    stringsUnicode.push(strBufUnicode.join(\"\"));\n  }\n  const names = [strings, stringsUnicode];\n  const platforms = [\"\\x00\\x01\", \"\\x00\\x03\"];\n  const encodings = [\"\\x00\\x00\", \"\\x00\\x01\"];\n  const languages = [\"\\x00\\x00\", \"\\x04\\x09\"];\n  const namesRecordCount = strings.length * platforms.length;\n  let nameTable = \"\\x00\\x00\" + string16(namesRecordCount) + string16(namesRecordCount * 12 + 6);\n  let strOffset = 0;\n  for (i = 0, ii = platforms.length; i < ii; i++) {\n    const strs = names[i];\n    for (j = 0, jj = strs.length; j < jj; j++) {\n      str = strs[j];\n      const nameRecord = platforms[i] + encodings[i] + languages[i] + string16(j) + string16(str.length) + string16(strOffset);\n      nameTable += nameRecord;\n      strOffset += str.length;\n    }\n  }\n  nameTable += strings.join(\"\") + stringsUnicode.join(\"\");\n  return nameTable;\n}\nclass Font {\n  constructor(name, file, properties) {\n    this.name = name;\n    this.psName = null;\n    this.mimetype = null;\n    this.disableFontFace = false;\n    this.loadedName = properties.loadedName;\n    this.isType3Font = properties.isType3Font;\n    this.missingFile = false;\n    this.cssFontInfo = properties.cssFontInfo;\n    this._charsCache = Object.create(null);\n    this._glyphCache = Object.create(null);\n    let isSerifFont = !!(properties.flags & FontFlags.Serif);\n    if (!isSerifFont && !properties.isSimulatedFlags) {\n      const baseName = name.replaceAll(/[,_]/g, \"-\").split(\"-\", 1)[0],\n        serifFonts = getSerifFonts();\n      for (const namePart of baseName.split(\"+\")) {\n        if (serifFonts[namePart]) {\n          isSerifFont = true;\n          break;\n        }\n      }\n    }\n    this.isSerifFont = isSerifFont;\n    this.isSymbolicFont = !!(properties.flags & FontFlags.Symbolic);\n    this.isMonospace = !!(properties.flags & FontFlags.FixedPitch);\n    let {\n      type,\n      subtype\n    } = properties;\n    this.type = type;\n    this.subtype = subtype;\n    this.systemFontInfo = properties.systemFontInfo;\n    const matches = name.match(/^InvalidPDFjsFont_(.*)_\\d+$/);\n    this.isInvalidPDFjsFont = !!matches;\n    if (this.isInvalidPDFjsFont) {\n      this.fallbackName = matches[1];\n    } else if (this.isMonospace) {\n      this.fallbackName = \"monospace\";\n    } else if (this.isSerifFont) {\n      this.fallbackName = \"serif\";\n    } else {\n      this.fallbackName = \"sans-serif\";\n    }\n    if (this.systemFontInfo?.guessFallback) {\n      this.systemFontInfo.guessFallback = false;\n      this.systemFontInfo.css += `,${this.fallbackName}`;\n    }\n    this.differences = properties.differences;\n    this.widths = properties.widths;\n    this.defaultWidth = properties.defaultWidth;\n    this.composite = properties.composite;\n    this.cMap = properties.cMap;\n    this.capHeight = properties.capHeight / PDF_GLYPH_SPACE_UNITS;\n    this.ascent = properties.ascent / PDF_GLYPH_SPACE_UNITS;\n    this.descent = properties.descent / PDF_GLYPH_SPACE_UNITS;\n    this.lineHeight = this.ascent - this.descent;\n    this.fontMatrix = properties.fontMatrix;\n    this.bbox = properties.bbox;\n    this.defaultEncoding = properties.defaultEncoding;\n    this.toUnicode = properties.toUnicode;\n    this.toFontChar = [];\n    if (properties.type === \"Type3\") {\n      for (let charCode = 0; charCode < 256; charCode++) {\n        this.toFontChar[charCode] = this.differences[charCode] || properties.defaultEncoding[charCode];\n      }\n      return;\n    }\n    this.cidEncoding = properties.cidEncoding || \"\";\n    this.vertical = !!properties.vertical;\n    if (this.vertical) {\n      this.vmetrics = properties.vmetrics;\n      this.defaultVMetrics = properties.defaultVMetrics;\n    }\n    if (!file || file.isEmpty) {\n      if (file) {\n        warn('Font file is empty in \"' + name + '\" (' + this.loadedName + \")\");\n      }\n      this.fallbackToSystemFont(properties);\n      return;\n    }\n    [type, subtype] = getFontFileType(file, properties);\n    if (type !== this.type || subtype !== this.subtype) {\n      info(\"Inconsistent font file Type/SubType, expected: \" + `${this.type}/${this.subtype} but found: ${type}/${subtype}.`);\n    }\n    let data;\n    try {\n      switch (type) {\n        case \"MMType1\":\n          info(\"MMType1 font (\" + name + \"), falling back to Type1.\");\n        case \"Type1\":\n        case \"CIDFontType0\":\n          this.mimetype = \"font/opentype\";\n          const cff = subtype === \"Type1C\" || subtype === \"CIDFontType0C\" ? new CFFFont(file, properties) : new Type1Font(name, file, properties);\n          adjustWidths(properties);\n          data = this.convert(name, cff, properties);\n          break;\n        case \"OpenType\":\n        case \"TrueType\":\n        case \"CIDFontType2\":\n          this.mimetype = \"font/opentype\";\n          data = this.checkAndRepair(name, file, properties);\n          if (this.isOpenType) {\n            adjustWidths(properties);\n            type = \"OpenType\";\n          }\n          break;\n        default:\n          throw new FormatError(`Font ${type} is not supported`);\n      }\n    } catch (e) {\n      warn(e);\n      this.fallbackToSystemFont(properties);\n      return;\n    }\n    amendFallbackToUnicode(properties);\n    this.data = data;\n    this.type = type;\n    this.subtype = subtype;\n    this.fontMatrix = properties.fontMatrix;\n    this.widths = properties.widths;\n    this.defaultWidth = properties.defaultWidth;\n    this.toUnicode = properties.toUnicode;\n    this.seacMap = properties.seacMap;\n  }\n  get renderer() {\n    const renderer = FontRendererFactory.create(this, SEAC_ANALYSIS_ENABLED);\n    return shadow(this, \"renderer\", renderer);\n  }\n  exportData(extraProperties = false) {\n    const exportDataProperties = extraProperties ? [...EXPORT_DATA_PROPERTIES, ...EXPORT_DATA_EXTRA_PROPERTIES] : EXPORT_DATA_PROPERTIES;\n    const data = Object.create(null);\n    let property, value;\n    for (property of exportDataProperties) {\n      value = this[property];\n      if (value !== undefined) {\n        data[property] = value;\n      }\n    }\n    return data;\n  }\n  fallbackToSystemFont(properties) {\n    this.missingFile = true;\n    const {\n      name,\n      type\n    } = this;\n    let fontName = normalizeFontName(name);\n    const stdFontMap = getStdFontMap(),\n      nonStdFontMap = getNonStdFontMap();\n    const isStandardFont = !!stdFontMap[fontName];\n    const isMappedToStandardFont = !!(nonStdFontMap[fontName] && stdFontMap[nonStdFontMap[fontName]]);\n    fontName = stdFontMap[fontName] || nonStdFontMap[fontName] || fontName;\n    const fontBasicMetricsMap = getFontBasicMetrics();\n    const metrics = fontBasicMetricsMap[fontName];\n    if (metrics) {\n      if (isNaN(this.ascent)) {\n        this.ascent = metrics.ascent / PDF_GLYPH_SPACE_UNITS;\n      }\n      if (isNaN(this.descent)) {\n        this.descent = metrics.descent / PDF_GLYPH_SPACE_UNITS;\n      }\n      if (isNaN(this.capHeight)) {\n        this.capHeight = metrics.capHeight / PDF_GLYPH_SPACE_UNITS;\n      }\n    }\n    this.bold = /bold/gi.test(fontName);\n    this.italic = /oblique|italic/gi.test(fontName);\n    this.black = /Black/g.test(name);\n    const isNarrow = /Narrow/g.test(name);\n    this.remeasure = (!isStandardFont || isNarrow) && Object.keys(this.widths).length > 0;\n    if ((isStandardFont || isMappedToStandardFont) && type === \"CIDFontType2\" && this.cidEncoding.startsWith(\"Identity-\")) {\n      const cidToGidMap = properties.cidToGidMap;\n      const map = [];\n      applyStandardFontGlyphMap(map, getGlyphMapForStandardFonts());\n      if (/Arial-?Black/i.test(name)) {\n        applyStandardFontGlyphMap(map, getSupplementalGlyphMapForArialBlack());\n      } else if (/Calibri/i.test(name)) {\n        applyStandardFontGlyphMap(map, getSupplementalGlyphMapForCalibri());\n      }\n      if (cidToGidMap) {\n        for (const charCode in map) {\n          const cid = map[charCode];\n          if (cidToGidMap[cid] !== undefined) {\n            map[+charCode] = cidToGidMap[cid];\n          }\n        }\n        if (cidToGidMap.length !== this.toUnicode.length && properties.hasIncludedToUnicodeMap && this.toUnicode instanceof IdentityToUnicodeMap) {\n          this.toUnicode.forEach(function (charCode, unicodeCharCode) {\n            const cid = map[charCode];\n            if (cidToGidMap[cid] === undefined) {\n              map[+charCode] = unicodeCharCode;\n            }\n          });\n        }\n      }\n      if (!(this.toUnicode instanceof IdentityToUnicodeMap)) {\n        this.toUnicode.forEach(function (charCode, unicodeCharCode) {\n          map[+charCode] = unicodeCharCode;\n        });\n      }\n      this.toFontChar = map;\n      this.toUnicode = new ToUnicodeMap(map);\n    } else if (/Symbol/i.test(fontName)) {\n      this.toFontChar = buildToFontChar(SymbolSetEncoding, getGlyphsUnicode(), this.differences);\n    } else if (/Dingbats/i.test(fontName)) {\n      this.toFontChar = buildToFontChar(ZapfDingbatsEncoding, getDingbatsGlyphsUnicode(), this.differences);\n    } else if (isStandardFont) {\n      const map = buildToFontChar(this.defaultEncoding, getGlyphsUnicode(), this.differences);\n      if (type === \"CIDFontType2\" && !this.cidEncoding.startsWith(\"Identity-\") && !(this.toUnicode instanceof IdentityToUnicodeMap)) {\n        this.toUnicode.forEach(function (charCode, unicodeCharCode) {\n          map[+charCode] = unicodeCharCode;\n        });\n      }\n      this.toFontChar = map;\n    } else {\n      const glyphsUnicodeMap = getGlyphsUnicode();\n      const map = [];\n      this.toUnicode.forEach((charCode, unicodeCharCode) => {\n        if (!this.composite) {\n          const glyphName = this.differences[charCode] || this.defaultEncoding[charCode];\n          const unicode = getUnicodeForGlyph(glyphName, glyphsUnicodeMap);\n          if (unicode !== -1) {\n            unicodeCharCode = unicode;\n          }\n        }\n        map[+charCode] = unicodeCharCode;\n      });\n      if (this.composite && this.toUnicode instanceof IdentityToUnicodeMap) {\n        if (/Tahoma|Verdana/i.test(name)) {\n          applyStandardFontGlyphMap(map, getGlyphMapForStandardFonts());\n        }\n      }\n      this.toFontChar = map;\n    }\n    amendFallbackToUnicode(properties);\n    this.loadedName = fontName.split(\"-\", 1)[0];\n  }\n  checkAndRepair(name, font, properties) {\n    const VALID_TABLES = [\"OS/2\", \"cmap\", \"head\", \"hhea\", \"hmtx\", \"maxp\", \"name\", \"post\", \"loca\", \"glyf\", \"fpgm\", \"prep\", \"cvt \", \"CFF \"];\n    function readTables(file, numTables) {\n      const tables = Object.create(null);\n      tables[\"OS/2\"] = null;\n      tables.cmap = null;\n      tables.head = null;\n      tables.hhea = null;\n      tables.hmtx = null;\n      tables.maxp = null;\n      tables.name = null;\n      tables.post = null;\n      for (let i = 0; i < numTables; i++) {\n        const table = readTableEntry(file);\n        if (!VALID_TABLES.includes(table.tag)) {\n          continue;\n        }\n        if (table.length === 0) {\n          continue;\n        }\n        tables[table.tag] = table;\n      }\n      return tables;\n    }\n    function readTableEntry(file) {\n      const tag = file.getString(4);\n      const checksum = file.getInt32() >>> 0;\n      const offset = file.getInt32() >>> 0;\n      const length = file.getInt32() >>> 0;\n      const previousPosition = file.pos;\n      file.pos = file.start || 0;\n      file.skip(offset);\n      const data = file.getBytes(length);\n      file.pos = previousPosition;\n      if (tag === \"head\") {\n        data[8] = data[9] = data[10] = data[11] = 0;\n        data[17] |= 0x20;\n      }\n      return {\n        tag,\n        checksum,\n        length,\n        offset,\n        data\n      };\n    }\n    function readOpenTypeHeader(ttf) {\n      return {\n        version: ttf.getString(4),\n        numTables: ttf.getUint16(),\n        searchRange: ttf.getUint16(),\n        entrySelector: ttf.getUint16(),\n        rangeShift: ttf.getUint16()\n      };\n    }\n    function readTrueTypeCollectionHeader(ttc) {\n      const ttcTag = ttc.getString(4);\n      assert(ttcTag === \"ttcf\", \"Must be a TrueType Collection font.\");\n      const majorVersion = ttc.getUint16();\n      const minorVersion = ttc.getUint16();\n      const numFonts = ttc.getInt32() >>> 0;\n      const offsetTable = [];\n      for (let i = 0; i < numFonts; i++) {\n        offsetTable.push(ttc.getInt32() >>> 0);\n      }\n      const header = {\n        ttcTag,\n        majorVersion,\n        minorVersion,\n        numFonts,\n        offsetTable\n      };\n      switch (majorVersion) {\n        case 1:\n          return header;\n        case 2:\n          header.dsigTag = ttc.getInt32() >>> 0;\n          header.dsigLength = ttc.getInt32() >>> 0;\n          header.dsigOffset = ttc.getInt32() >>> 0;\n          return header;\n      }\n      throw new FormatError(`Invalid TrueType Collection majorVersion: ${majorVersion}.`);\n    }\n    function readTrueTypeCollectionData(ttc, fontName) {\n      const {\n        numFonts,\n        offsetTable\n      } = readTrueTypeCollectionHeader(ttc);\n      const fontNameParts = fontName.split(\"+\");\n      let fallbackData;\n      for (let i = 0; i < numFonts; i++) {\n        ttc.pos = (ttc.start || 0) + offsetTable[i];\n        const potentialHeader = readOpenTypeHeader(ttc);\n        const potentialTables = readTables(ttc, potentialHeader.numTables);\n        if (!potentialTables.name) {\n          throw new FormatError('TrueType Collection font must contain a \"name\" table.');\n        }\n        const [nameTable] = readNameTable(potentialTables.name);\n        for (let j = 0, jj = nameTable.length; j < jj; j++) {\n          for (let k = 0, kk = nameTable[j].length; k < kk; k++) {\n            const nameEntry = nameTable[j][k]?.replaceAll(/\\s/g, \"\");\n            if (!nameEntry) {\n              continue;\n            }\n            if (nameEntry === fontName) {\n              return {\n                header: potentialHeader,\n                tables: potentialTables\n              };\n            }\n            if (fontNameParts.length < 2) {\n              continue;\n            }\n            for (const part of fontNameParts) {\n              if (nameEntry === part) {\n                fallbackData = {\n                  name: part,\n                  header: potentialHeader,\n                  tables: potentialTables\n                };\n              }\n            }\n          }\n        }\n      }\n      if (fallbackData) {\n        warn(`TrueType Collection does not contain \"${fontName}\" font, ` + `falling back to \"${fallbackData.name}\" font instead.`);\n        return {\n          header: fallbackData.header,\n          tables: fallbackData.tables\n        };\n      }\n      throw new FormatError(`TrueType Collection does not contain \"${fontName}\" font.`);\n    }\n    function readCmapTable(cmap, file, isSymbolicFont, hasEncoding) {\n      if (!cmap) {\n        warn(\"No cmap table available.\");\n        return {\n          platformId: -1,\n          encodingId: -1,\n          mappings: [],\n          hasShortCmap: false\n        };\n      }\n      let segment;\n      let start = (file.start || 0) + cmap.offset;\n      file.pos = start;\n      file.skip(2);\n      const numTables = file.getUint16();\n      let potentialTable;\n      let canBreak = false;\n      for (let i = 0; i < numTables; i++) {\n        const platformId = file.getUint16();\n        const encodingId = file.getUint16();\n        const offset = file.getInt32() >>> 0;\n        let useTable = false;\n        if (potentialTable?.platformId === platformId && potentialTable?.encodingId === encodingId) {\n          continue;\n        }\n        if (platformId === 0 && (encodingId === 0 || encodingId === 1 || encodingId === 3)) {\n          useTable = true;\n        } else if (platformId === 1 && encodingId === 0) {\n          useTable = true;\n        } else if (platformId === 3 && encodingId === 1 && (hasEncoding || !potentialTable)) {\n          useTable = true;\n          if (!isSymbolicFont) {\n            canBreak = true;\n          }\n        } else if (isSymbolicFont && platformId === 3 && encodingId === 0) {\n          useTable = true;\n          let correctlySorted = true;\n          if (i < numTables - 1) {\n            const nextBytes = file.peekBytes(2),\n              nextPlatformId = int16(nextBytes[0], nextBytes[1]);\n            if (nextPlatformId < platformId) {\n              correctlySorted = false;\n            }\n          }\n          if (correctlySorted) {\n            canBreak = true;\n          }\n        }\n        if (useTable) {\n          potentialTable = {\n            platformId,\n            encodingId,\n            offset\n          };\n        }\n        if (canBreak) {\n          break;\n        }\n      }\n      if (potentialTable) {\n        file.pos = start + potentialTable.offset;\n      }\n      if (!potentialTable || file.peekByte() === -1) {\n        warn(\"Could not find a preferred cmap table.\");\n        return {\n          platformId: -1,\n          encodingId: -1,\n          mappings: [],\n          hasShortCmap: false\n        };\n      }\n      const format = file.getUint16();\n      let hasShortCmap = false;\n      const mappings = [];\n      let j, glyphId;\n      if (format === 0) {\n        file.skip(2 + 2);\n        for (j = 0; j < 256; j++) {\n          const index = file.getByte();\n          if (!index) {\n            continue;\n          }\n          mappings.push({\n            charCode: j,\n            glyphId: index\n          });\n        }\n        hasShortCmap = true;\n      } else if (format === 2) {\n        file.skip(2 + 2);\n        const subHeaderKeys = [];\n        let maxSubHeaderKey = 0;\n        for (let i = 0; i < 256; i++) {\n          const subHeaderKey = file.getUint16() >> 3;\n          subHeaderKeys.push(subHeaderKey);\n          maxSubHeaderKey = Math.max(subHeaderKey, maxSubHeaderKey);\n        }\n        const subHeaders = [];\n        for (let i = 0; i <= maxSubHeaderKey; i++) {\n          subHeaders.push({\n            firstCode: file.getUint16(),\n            entryCount: file.getUint16(),\n            idDelta: signedInt16(file.getByte(), file.getByte()),\n            idRangePos: file.pos + file.getUint16()\n          });\n        }\n        for (let i = 0; i < 256; i++) {\n          if (subHeaderKeys[i] === 0) {\n            file.pos = subHeaders[0].idRangePos + 2 * i;\n            glyphId = file.getUint16();\n            mappings.push({\n              charCode: i,\n              glyphId\n            });\n          } else {\n            const s = subHeaders[subHeaderKeys[i]];\n            for (j = 0; j < s.entryCount; j++) {\n              const charCode = (i << 8) + j + s.firstCode;\n              file.pos = s.idRangePos + 2 * j;\n              glyphId = file.getUint16();\n              if (glyphId !== 0) {\n                glyphId = (glyphId + s.idDelta) % 65536;\n              }\n              mappings.push({\n                charCode,\n                glyphId\n              });\n            }\n          }\n        }\n      } else if (format === 4) {\n        file.skip(2 + 2);\n        const segCount = file.getUint16() >> 1;\n        file.skip(6);\n        const segments = [];\n        let segIndex;\n        for (segIndex = 0; segIndex < segCount; segIndex++) {\n          segments.push({\n            end: file.getUint16()\n          });\n        }\n        file.skip(2);\n        for (segIndex = 0; segIndex < segCount; segIndex++) {\n          segments[segIndex].start = file.getUint16();\n        }\n        for (segIndex = 0; segIndex < segCount; segIndex++) {\n          segments[segIndex].delta = file.getUint16();\n        }\n        let offsetsCount = 0,\n          offsetIndex;\n        for (segIndex = 0; segIndex < segCount; segIndex++) {\n          segment = segments[segIndex];\n          const rangeOffset = file.getUint16();\n          if (!rangeOffset) {\n            segment.offsetIndex = -1;\n            continue;\n          }\n          offsetIndex = (rangeOffset >> 1) - (segCount - segIndex);\n          segment.offsetIndex = offsetIndex;\n          offsetsCount = Math.max(offsetsCount, offsetIndex + segment.end - segment.start + 1);\n        }\n        const offsets = [];\n        for (j = 0; j < offsetsCount; j++) {\n          offsets.push(file.getUint16());\n        }\n        for (segIndex = 0; segIndex < segCount; segIndex++) {\n          segment = segments[segIndex];\n          start = segment.start;\n          const end = segment.end;\n          const delta = segment.delta;\n          offsetIndex = segment.offsetIndex;\n          for (j = start; j <= end; j++) {\n            if (j === 0xffff) {\n              continue;\n            }\n            glyphId = offsetIndex < 0 ? j : offsets[offsetIndex + j - start];\n            glyphId = glyphId + delta & 0xffff;\n            mappings.push({\n              charCode: j,\n              glyphId\n            });\n          }\n        }\n      } else if (format === 6) {\n        file.skip(2 + 2);\n        const firstCode = file.getUint16();\n        const entryCount = file.getUint16();\n        for (j = 0; j < entryCount; j++) {\n          glyphId = file.getUint16();\n          const charCode = firstCode + j;\n          mappings.push({\n            charCode,\n            glyphId\n          });\n        }\n      } else if (format === 12) {\n        file.skip(2 + 4 + 4);\n        const nGroups = file.getInt32() >>> 0;\n        for (j = 0; j < nGroups; j++) {\n          const startCharCode = file.getInt32() >>> 0;\n          const endCharCode = file.getInt32() >>> 0;\n          let glyphCode = file.getInt32() >>> 0;\n          for (let charCode = startCharCode; charCode <= endCharCode; charCode++) {\n            mappings.push({\n              charCode,\n              glyphId: glyphCode++\n            });\n          }\n        }\n      } else {\n        warn(\"cmap table has unsupported format: \" + format);\n        return {\n          platformId: -1,\n          encodingId: -1,\n          mappings: [],\n          hasShortCmap: false\n        };\n      }\n      mappings.sort(function (a, b) {\n        return a.charCode - b.charCode;\n      });\n      for (let i = 1; i < mappings.length; i++) {\n        if (mappings[i - 1].charCode === mappings[i].charCode) {\n          mappings.splice(i, 1);\n          i--;\n        }\n      }\n      return {\n        platformId: potentialTable.platformId,\n        encodingId: potentialTable.encodingId,\n        mappings,\n        hasShortCmap\n      };\n    }\n    function sanitizeMetrics(file, header, metrics, headTable, numGlyphs, dupFirstEntry) {\n      if (!header) {\n        if (metrics) {\n          metrics.data = null;\n        }\n        return;\n      }\n      file.pos = (file.start || 0) + header.offset;\n      file.pos += 4;\n      file.pos += 2;\n      file.pos += 2;\n      file.pos += 2;\n      file.pos += 2;\n      file.pos += 2;\n      file.pos += 2;\n      file.pos += 2;\n      file.pos += 2;\n      file.pos += 2;\n      const caretOffset = file.getUint16();\n      file.pos += 8;\n      file.pos += 2;\n      let numOfMetrics = file.getUint16();\n      if (caretOffset !== 0) {\n        const macStyle = int16(headTable.data[44], headTable.data[45]);\n        if (!(macStyle & 2)) {\n          header.data[22] = 0;\n          header.data[23] = 0;\n        }\n      }\n      if (numOfMetrics > numGlyphs) {\n        info(`The numOfMetrics (${numOfMetrics}) should not be ` + `greater than the numGlyphs (${numGlyphs}).`);\n        numOfMetrics = numGlyphs;\n        header.data[34] = (numOfMetrics & 0xff00) >> 8;\n        header.data[35] = numOfMetrics & 0x00ff;\n      }\n      const numOfSidebearings = numGlyphs - numOfMetrics;\n      const numMissing = numOfSidebearings - (metrics.length - numOfMetrics * 4 >> 1);\n      if (numMissing > 0) {\n        const entries = new Uint8Array(metrics.length + numMissing * 2);\n        entries.set(metrics.data);\n        if (dupFirstEntry) {\n          entries[metrics.length] = metrics.data[2];\n          entries[metrics.length + 1] = metrics.data[3];\n        }\n        metrics.data = entries;\n      }\n    }\n    function sanitizeGlyph(source, sourceStart, sourceEnd, dest, destStart, hintsValid) {\n      const glyphProfile = {\n        length: 0,\n        sizeOfInstructions: 0\n      };\n      if (sourceStart < 0 || sourceStart >= source.length || sourceEnd > source.length || sourceEnd - sourceStart <= 12) {\n        return glyphProfile;\n      }\n      const glyf = source.subarray(sourceStart, sourceEnd);\n      const xMin = signedInt16(glyf[2], glyf[3]);\n      const yMin = signedInt16(glyf[4], glyf[5]);\n      const xMax = signedInt16(glyf[6], glyf[7]);\n      const yMax = signedInt16(glyf[8], glyf[9]);\n      if (xMin > xMax) {\n        writeSignedInt16(glyf, 2, xMax);\n        writeSignedInt16(glyf, 6, xMin);\n      }\n      if (yMin > yMax) {\n        writeSignedInt16(glyf, 4, yMax);\n        writeSignedInt16(glyf, 8, yMin);\n      }\n      const contoursCount = signedInt16(glyf[0], glyf[1]);\n      if (contoursCount < 0) {\n        if (contoursCount < -1) {\n          return glyphProfile;\n        }\n        dest.set(glyf, destStart);\n        glyphProfile.length = glyf.length;\n        return glyphProfile;\n      }\n      let i,\n        j = 10,\n        flagsCount = 0;\n      for (i = 0; i < contoursCount; i++) {\n        const endPoint = glyf[j] << 8 | glyf[j + 1];\n        flagsCount = endPoint + 1;\n        j += 2;\n      }\n      const instructionsStart = j;\n      const instructionsLength = glyf[j] << 8 | glyf[j + 1];\n      glyphProfile.sizeOfInstructions = instructionsLength;\n      j += 2 + instructionsLength;\n      const instructionsEnd = j;\n      let coordinatesLength = 0;\n      for (i = 0; i < flagsCount; i++) {\n        const flag = glyf[j++];\n        if (flag & 0xc0) {\n          glyf[j - 1] = flag & 0x3f;\n        }\n        let xLength = 2;\n        if (flag & 2) {\n          xLength = 1;\n        } else if (flag & 16) {\n          xLength = 0;\n        }\n        let yLength = 2;\n        if (flag & 4) {\n          yLength = 1;\n        } else if (flag & 32) {\n          yLength = 0;\n        }\n        const xyLength = xLength + yLength;\n        coordinatesLength += xyLength;\n        if (flag & 8) {\n          const repeat = glyf[j++];\n          if (repeat === 0) {\n            glyf[j - 1] ^= 8;\n          }\n          i += repeat;\n          coordinatesLength += repeat * xyLength;\n        }\n      }\n      if (coordinatesLength === 0) {\n        return glyphProfile;\n      }\n      let glyphDataLength = j + coordinatesLength;\n      if (glyphDataLength > glyf.length) {\n        return glyphProfile;\n      }\n      if (!hintsValid && instructionsLength > 0) {\n        dest.set(glyf.subarray(0, instructionsStart), destStart);\n        dest.set([0, 0], destStart + instructionsStart);\n        dest.set(glyf.subarray(instructionsEnd, glyphDataLength), destStart + instructionsStart + 2);\n        glyphDataLength -= instructionsLength;\n        if (glyf.length - glyphDataLength > 3) {\n          glyphDataLength = glyphDataLength + 3 & ~3;\n        }\n        glyphProfile.length = glyphDataLength;\n        return glyphProfile;\n      }\n      if (glyf.length - glyphDataLength > 3) {\n        glyphDataLength = glyphDataLength + 3 & ~3;\n        dest.set(glyf.subarray(0, glyphDataLength), destStart);\n        glyphProfile.length = glyphDataLength;\n        return glyphProfile;\n      }\n      dest.set(glyf, destStart);\n      glyphProfile.length = glyf.length;\n      return glyphProfile;\n    }\n    function sanitizeHead(head, numGlyphs, locaLength) {\n      const data = head.data;\n      const version = int32(data[0], data[1], data[2], data[3]);\n      if (version >> 16 !== 1) {\n        info(\"Attempting to fix invalid version in head table: \" + version);\n        data[0] = 0;\n        data[1] = 1;\n        data[2] = 0;\n        data[3] = 0;\n      }\n      const indexToLocFormat = int16(data[50], data[51]);\n      if (indexToLocFormat < 0 || indexToLocFormat > 1) {\n        info(\"Attempting to fix invalid indexToLocFormat in head table: \" + indexToLocFormat);\n        const numGlyphsPlusOne = numGlyphs + 1;\n        if (locaLength === numGlyphsPlusOne << 1) {\n          data[50] = 0;\n          data[51] = 0;\n        } else if (locaLength === numGlyphsPlusOne << 2) {\n          data[50] = 0;\n          data[51] = 1;\n        } else {\n          throw new FormatError(\"Could not fix indexToLocFormat: \" + indexToLocFormat);\n        }\n      }\n    }\n    function sanitizeGlyphLocations(loca, glyf, numGlyphs, isGlyphLocationsLong, hintsValid, dupFirstEntry, maxSizeOfInstructions) {\n      let itemSize, itemDecode, itemEncode;\n      if (isGlyphLocationsLong) {\n        itemSize = 4;\n        itemDecode = function fontItemDecodeLong(data, offset) {\n          return data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3];\n        };\n        itemEncode = function fontItemEncodeLong(data, offset, value) {\n          data[offset] = value >>> 24 & 0xff;\n          data[offset + 1] = value >> 16 & 0xff;\n          data[offset + 2] = value >> 8 & 0xff;\n          data[offset + 3] = value & 0xff;\n        };\n      } else {\n        itemSize = 2;\n        itemDecode = function fontItemDecode(data, offset) {\n          return data[offset] << 9 | data[offset + 1] << 1;\n        };\n        itemEncode = function fontItemEncode(data, offset, value) {\n          data[offset] = value >> 9 & 0xff;\n          data[offset + 1] = value >> 1 & 0xff;\n        };\n      }\n      const numGlyphsOut = dupFirstEntry ? numGlyphs + 1 : numGlyphs;\n      const locaDataSize = itemSize * (1 + numGlyphsOut);\n      const locaData = new Uint8Array(locaDataSize);\n      locaData.set(loca.data.subarray(0, locaDataSize));\n      loca.data = locaData;\n      const oldGlyfData = glyf.data;\n      const oldGlyfDataLength = oldGlyfData.length;\n      const newGlyfData = new Uint8Array(oldGlyfDataLength);\n      let i, j;\n      const locaEntries = [];\n      for (i = 0, j = 0; i < numGlyphs + 1; i++, j += itemSize) {\n        let offset = itemDecode(locaData, j);\n        if (offset > oldGlyfDataLength) {\n          offset = oldGlyfDataLength;\n        }\n        locaEntries.push({\n          index: i,\n          offset,\n          endOffset: 0\n        });\n      }\n      locaEntries.sort((a, b) => a.offset - b.offset);\n      for (i = 0; i < numGlyphs; i++) {\n        locaEntries[i].endOffset = locaEntries[i + 1].offset;\n      }\n      locaEntries.sort((a, b) => a.index - b.index);\n      for (i = 0; i < numGlyphs; i++) {\n        const {\n          offset,\n          endOffset\n        } = locaEntries[i];\n        if (offset !== 0 || endOffset !== 0) {\n          break;\n        }\n        const nextOffset = locaEntries[i + 1].offset;\n        if (nextOffset === 0) {\n          continue;\n        }\n        locaEntries[i].endOffset = nextOffset;\n        break;\n      }\n      const last = locaEntries.at(-2);\n      if (last.offset !== 0 && last.endOffset === 0) {\n        last.endOffset = oldGlyfDataLength;\n      }\n      const missingGlyphs = Object.create(null);\n      let writeOffset = 0;\n      itemEncode(locaData, 0, writeOffset);\n      for (i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) {\n        const glyphProfile = sanitizeGlyph(oldGlyfData, locaEntries[i].offset, locaEntries[i].endOffset, newGlyfData, writeOffset, hintsValid);\n        const newLength = glyphProfile.length;\n        if (newLength === 0) {\n          missingGlyphs[i] = true;\n        }\n        if (glyphProfile.sizeOfInstructions > maxSizeOfInstructions) {\n          maxSizeOfInstructions = glyphProfile.sizeOfInstructions;\n        }\n        writeOffset += newLength;\n        itemEncode(locaData, j, writeOffset);\n      }\n      if (writeOffset === 0) {\n        const simpleGlyph = new Uint8Array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0]);\n        for (i = 0, j = itemSize; i < numGlyphsOut; i++, j += itemSize) {\n          itemEncode(locaData, j, simpleGlyph.length);\n        }\n        glyf.data = simpleGlyph;\n      } else if (dupFirstEntry) {\n        const firstEntryLength = itemDecode(locaData, itemSize);\n        if (newGlyfData.length > firstEntryLength + writeOffset) {\n          glyf.data = newGlyfData.subarray(0, firstEntryLength + writeOffset);\n        } else {\n          glyf.data = new Uint8Array(firstEntryLength + writeOffset);\n          glyf.data.set(newGlyfData.subarray(0, writeOffset));\n        }\n        glyf.data.set(newGlyfData.subarray(0, firstEntryLength), writeOffset);\n        itemEncode(loca.data, locaData.length - itemSize, writeOffset + firstEntryLength);\n      } else {\n        glyf.data = newGlyfData.subarray(0, writeOffset);\n      }\n      return {\n        missingGlyphs,\n        maxSizeOfInstructions\n      };\n    }\n    function readPostScriptTable(post, propertiesObj, maxpNumGlyphs) {\n      const start = (font.start || 0) + post.offset;\n      font.pos = start;\n      const length = post.length,\n        end = start + length;\n      const version = font.getInt32();\n      font.skip(28);\n      let glyphNames;\n      let valid = true;\n      let i;\n      switch (version) {\n        case 0x00010000:\n          glyphNames = MacStandardGlyphOrdering;\n          break;\n        case 0x00020000:\n          const numGlyphs = font.getUint16();\n          if (numGlyphs !== maxpNumGlyphs) {\n            valid = false;\n            break;\n          }\n          const glyphNameIndexes = [];\n          for (i = 0; i < numGlyphs; ++i) {\n            const index = font.getUint16();\n            if (index >= 32768) {\n              valid = false;\n              break;\n            }\n            glyphNameIndexes.push(index);\n          }\n          if (!valid) {\n            break;\n          }\n          const customNames = [],\n            strBuf = [];\n          while (font.pos < end) {\n            const stringLength = font.getByte();\n            strBuf.length = stringLength;\n            for (i = 0; i < stringLength; ++i) {\n              strBuf[i] = String.fromCharCode(font.getByte());\n            }\n            customNames.push(strBuf.join(\"\"));\n          }\n          glyphNames = [];\n          for (i = 0; i < numGlyphs; ++i) {\n            const j = glyphNameIndexes[i];\n            if (j < 258) {\n              glyphNames.push(MacStandardGlyphOrdering[j]);\n              continue;\n            }\n            glyphNames.push(customNames[j - 258]);\n          }\n          break;\n        case 0x00030000:\n          break;\n        default:\n          warn(\"Unknown/unsupported post table version \" + version);\n          valid = false;\n          if (propertiesObj.defaultEncoding) {\n            glyphNames = propertiesObj.defaultEncoding;\n          }\n          break;\n      }\n      propertiesObj.glyphNames = glyphNames;\n      return valid;\n    }\n    function readNameTable(nameTable) {\n      const start = (font.start || 0) + nameTable.offset;\n      font.pos = start;\n      const names = [[], []],\n        records = [];\n      const length = nameTable.length,\n        end = start + length;\n      const format = font.getUint16();\n      const FORMAT_0_HEADER_LENGTH = 6;\n      if (format !== 0 || length < FORMAT_0_HEADER_LENGTH) {\n        return [names, records];\n      }\n      const numRecords = font.getUint16();\n      const stringsStart = font.getUint16();\n      const NAME_RECORD_LENGTH = 12;\n      let i, ii;\n      for (i = 0; i < numRecords && font.pos + NAME_RECORD_LENGTH <= end; i++) {\n        const r = {\n          platform: font.getUint16(),\n          encoding: font.getUint16(),\n          language: font.getUint16(),\n          name: font.getUint16(),\n          length: font.getUint16(),\n          offset: font.getUint16()\n        };\n        if (isMacNameRecord(r) || isWinNameRecord(r)) {\n          records.push(r);\n        }\n      }\n      for (i = 0, ii = records.length; i < ii; i++) {\n        const record = records[i];\n        if (record.length <= 0) {\n          continue;\n        }\n        const pos = start + stringsStart + record.offset;\n        if (pos + record.length > end) {\n          continue;\n        }\n        font.pos = pos;\n        const nameIndex = record.name;\n        if (record.encoding) {\n          let str = \"\";\n          for (let j = 0, jj = record.length; j < jj; j += 2) {\n            str += String.fromCharCode(font.getUint16());\n          }\n          names[1][nameIndex] = str;\n        } else {\n          names[0][nameIndex] = font.getString(record.length);\n        }\n      }\n      return [names, records];\n    }\n    const TTOpsStackDeltas = [0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -2, -2, 0, 0, -2, -5, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, 1, -1, -999, 0, 1, 0, -1, -2, 0, -1, -2, -1, -1, 0, -1, -1, 0, 0, -999, -999, -1, -1, -1, -1, -2, -999, -2, -2, -999, 0, -2, -2, 0, 0, -2, 0, -2, 0, 0, 0, -2, -1, -1, 1, 1, 0, 0, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, 0, -999, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -999, -999, -999, -999, -999, -1, -1, -2, -2, 0, 0, 0, 0, -1, -1, -999, -2, -2, 0, 0, -1, -2, -2, 0, 0, 0, -1, -1, -1, -2];\n    function sanitizeTTProgram(table, ttContext) {\n      let data = table.data;\n      let i = 0,\n        j,\n        n,\n        b,\n        funcId,\n        pc,\n        lastEndf = 0,\n        lastDeff = 0;\n      const stack = [];\n      const callstack = [];\n      const functionsCalled = [];\n      let tooComplexToFollowFunctions = ttContext.tooComplexToFollowFunctions;\n      let inFDEF = false,\n        ifLevel = 0,\n        inELSE = 0;\n      for (let ii = data.length; i < ii;) {\n        const op = data[i++];\n        if (op === 0x40) {\n          n = data[i++];\n          if (inFDEF || inELSE) {\n            i += n;\n          } else {\n            for (j = 0; j < n; j++) {\n              stack.push(data[i++]);\n            }\n          }\n        } else if (op === 0x41) {\n          n = data[i++];\n          if (inFDEF || inELSE) {\n            i += n * 2;\n          } else {\n            for (j = 0; j < n; j++) {\n              b = data[i++];\n              stack.push(b << 8 | data[i++]);\n            }\n          }\n        } else if ((op & 0xf8) === 0xb0) {\n          n = op - 0xb0 + 1;\n          if (inFDEF || inELSE) {\n            i += n;\n          } else {\n            for (j = 0; j < n; j++) {\n              stack.push(data[i++]);\n            }\n          }\n        } else if ((op & 0xf8) === 0xb8) {\n          n = op - 0xb8 + 1;\n          if (inFDEF || inELSE) {\n            i += n * 2;\n          } else {\n            for (j = 0; j < n; j++) {\n              b = data[i++];\n              stack.push(b << 8 | data[i++]);\n            }\n          }\n        } else if (op === 0x2b && !tooComplexToFollowFunctions) {\n          if (!inFDEF && !inELSE) {\n            funcId = stack.at(-1);\n            if (isNaN(funcId)) {\n              info(\"TT: CALL empty stack (or invalid entry).\");\n            } else {\n              ttContext.functionsUsed[funcId] = true;\n              if (funcId in ttContext.functionsStackDeltas) {\n                const newStackLength = stack.length + ttContext.functionsStackDeltas[funcId];\n                if (newStackLength < 0) {\n                  warn(\"TT: CALL invalid functions stack delta.\");\n                  ttContext.hintsValid = false;\n                  return;\n                }\n                stack.length = newStackLength;\n              } else if (funcId in ttContext.functionsDefined && !functionsCalled.includes(funcId)) {\n                callstack.push({\n                  data,\n                  i,\n                  stackTop: stack.length - 1\n                });\n                functionsCalled.push(funcId);\n                pc = ttContext.functionsDefined[funcId];\n                if (!pc) {\n                  warn(\"TT: CALL non-existent function\");\n                  ttContext.hintsValid = false;\n                  return;\n                }\n                data = pc.data;\n                i = pc.i;\n              }\n            }\n          }\n        } else if (op === 0x2c && !tooComplexToFollowFunctions) {\n          if (inFDEF || inELSE) {\n            warn(\"TT: nested FDEFs not allowed\");\n            tooComplexToFollowFunctions = true;\n          }\n          inFDEF = true;\n          lastDeff = i;\n          funcId = stack.pop();\n          ttContext.functionsDefined[funcId] = {\n            data,\n            i\n          };\n        } else if (op === 0x2d) {\n          if (inFDEF) {\n            inFDEF = false;\n            lastEndf = i;\n          } else {\n            pc = callstack.pop();\n            if (!pc) {\n              warn(\"TT: ENDF bad stack\");\n              ttContext.hintsValid = false;\n              return;\n            }\n            funcId = functionsCalled.pop();\n            data = pc.data;\n            i = pc.i;\n            ttContext.functionsStackDeltas[funcId] = stack.length - pc.stackTop;\n          }\n        } else if (op === 0x89) {\n          if (inFDEF || inELSE) {\n            warn(\"TT: nested IDEFs not allowed\");\n            tooComplexToFollowFunctions = true;\n          }\n          inFDEF = true;\n          lastDeff = i;\n        } else if (op === 0x58) {\n          ++ifLevel;\n        } else if (op === 0x1b) {\n          inELSE = ifLevel;\n        } else if (op === 0x59) {\n          if (inELSE === ifLevel) {\n            inELSE = 0;\n          }\n          --ifLevel;\n        } else if (op === 0x1c) {\n          if (!inFDEF && !inELSE) {\n            const offset = stack.at(-1);\n            if (offset > 0) {\n              i += offset - 1;\n            }\n          }\n        }\n        if (!inFDEF && !inELSE) {\n          let stackDelta = 0;\n          if (op <= 0x8e) {\n            stackDelta = TTOpsStackDeltas[op];\n          } else if (op >= 0xc0 && op <= 0xdf) {\n            stackDelta = -1;\n          } else if (op >= 0xe0) {\n            stackDelta = -2;\n          }\n          if (op >= 0x71 && op <= 0x75) {\n            n = stack.pop();\n            if (!isNaN(n)) {\n              stackDelta = -n * 2;\n            }\n          }\n          while (stackDelta < 0 && stack.length > 0) {\n            stack.pop();\n            stackDelta++;\n          }\n          while (stackDelta > 0) {\n            stack.push(NaN);\n            stackDelta--;\n          }\n        }\n      }\n      ttContext.tooComplexToFollowFunctions = tooComplexToFollowFunctions;\n      const content = [data];\n      if (i > data.length) {\n        content.push(new Uint8Array(i - data.length));\n      }\n      if (lastDeff > lastEndf) {\n        warn(\"TT: complementing a missing function tail\");\n        content.push(new Uint8Array([0x22, 0x2d]));\n      }\n      foldTTTable(table, content);\n    }\n    function checkInvalidFunctions(ttContext, maxFunctionDefs) {\n      if (ttContext.tooComplexToFollowFunctions) {\n        return;\n      }\n      if (ttContext.functionsDefined.length > maxFunctionDefs) {\n        warn(\"TT: more functions defined than expected\");\n        ttContext.hintsValid = false;\n        return;\n      }\n      for (let j = 0, jj = ttContext.functionsUsed.length; j < jj; j++) {\n        if (j > maxFunctionDefs) {\n          warn(\"TT: invalid function id: \" + j);\n          ttContext.hintsValid = false;\n          return;\n        }\n        if (ttContext.functionsUsed[j] && !ttContext.functionsDefined[j]) {\n          warn(\"TT: undefined function: \" + j);\n          ttContext.hintsValid = false;\n          return;\n        }\n      }\n    }\n    function foldTTTable(table, content) {\n      if (content.length > 1) {\n        let newLength = 0;\n        let j, jj;\n        for (j = 0, jj = content.length; j < jj; j++) {\n          newLength += content[j].length;\n        }\n        newLength = newLength + 3 & ~3;\n        const result = new Uint8Array(newLength);\n        let pos = 0;\n        for (j = 0, jj = content.length; j < jj; j++) {\n          result.set(content[j], pos);\n          pos += content[j].length;\n        }\n        table.data = result;\n        table.length = newLength;\n      }\n    }\n    function sanitizeTTPrograms(fpgm, prep, cvt, maxFunctionDefs) {\n      const ttContext = {\n        functionsDefined: [],\n        functionsUsed: [],\n        functionsStackDeltas: [],\n        tooComplexToFollowFunctions: false,\n        hintsValid: true\n      };\n      if (fpgm) {\n        sanitizeTTProgram(fpgm, ttContext);\n      }\n      if (prep) {\n        sanitizeTTProgram(prep, ttContext);\n      }\n      if (fpgm) {\n        checkInvalidFunctions(ttContext, maxFunctionDefs);\n      }\n      if (cvt && cvt.length & 1) {\n        const cvtData = new Uint8Array(cvt.length + 1);\n        cvtData.set(cvt.data);\n        cvt.data = cvtData;\n      }\n      return ttContext.hintsValid;\n    }\n    font = new Stream(new Uint8Array(font.getBytes()));\n    let header, tables;\n    if (isTrueTypeCollectionFile(font)) {\n      const ttcData = readTrueTypeCollectionData(font, this.name);\n      header = ttcData.header;\n      tables = ttcData.tables;\n    } else {\n      header = readOpenTypeHeader(font);\n      tables = readTables(font, header.numTables);\n    }\n    let cff, cffFile;\n    const isTrueType = !tables[\"CFF \"];\n    if (!isTrueType) {\n      const isComposite = properties.composite && (properties.cidToGidMap?.length > 0 || !(properties.cMap instanceof IdentityCMap));\n      if (header.version === \"OTTO\" && !isComposite || !tables.head || !tables.hhea || !tables.maxp || !tables.post) {\n        cffFile = new Stream(tables[\"CFF \"].data);\n        cff = new CFFFont(cffFile, properties);\n        adjustWidths(properties);\n        return this.convert(name, cff, properties);\n      }\n      delete tables.glyf;\n      delete tables.loca;\n      delete tables.fpgm;\n      delete tables.prep;\n      delete tables[\"cvt \"];\n      this.isOpenType = true;\n    } else {\n      if (!tables.loca) {\n        throw new FormatError('Required \"loca\" table is not found');\n      }\n      if (!tables.glyf) {\n        warn('Required \"glyf\" table is not found -- trying to recover.');\n        tables.glyf = {\n          tag: \"glyf\",\n          data: new Uint8Array(0)\n        };\n      }\n      this.isOpenType = false;\n    }\n    if (!tables.maxp) {\n      throw new FormatError('Required \"maxp\" table is not found');\n    }\n    font.pos = (font.start || 0) + tables.maxp.offset;\n    let version = font.getInt32();\n    const numGlyphs = font.getUint16();\n    if (version !== 0x00010000 && version !== 0x00005000) {\n      if (tables.maxp.length === 6) {\n        version = 0x0005000;\n      } else if (tables.maxp.length >= 32) {\n        version = 0x00010000;\n      } else {\n        throw new FormatError(`\"maxp\" table has a wrong version number`);\n      }\n      writeUint32(tables.maxp.data, 0, version);\n    }\n    if (properties.scaleFactors?.length === numGlyphs && isTrueType) {\n      const {\n        scaleFactors\n      } = properties;\n      const isGlyphLocationsLong = int16(tables.head.data[50], tables.head.data[51]);\n      const glyphs = new GlyfTable({\n        glyfTable: tables.glyf.data,\n        isGlyphLocationsLong,\n        locaTable: tables.loca.data,\n        numGlyphs\n      });\n      glyphs.scale(scaleFactors);\n      const {\n        glyf,\n        loca,\n        isLocationLong\n      } = glyphs.write();\n      tables.glyf.data = glyf;\n      tables.loca.data = loca;\n      if (isLocationLong !== !!isGlyphLocationsLong) {\n        tables.head.data[50] = 0;\n        tables.head.data[51] = isLocationLong ? 1 : 0;\n      }\n      const metrics = tables.hmtx.data;\n      for (let i = 0; i < numGlyphs; i++) {\n        const j = 4 * i;\n        const advanceWidth = Math.round(scaleFactors[i] * int16(metrics[j], metrics[j + 1]));\n        metrics[j] = advanceWidth >> 8 & 0xff;\n        metrics[j + 1] = advanceWidth & 0xff;\n        const lsb = Math.round(scaleFactors[i] * signedInt16(metrics[j + 2], metrics[j + 3]));\n        writeSignedInt16(metrics, j + 2, lsb);\n      }\n    }\n    let numGlyphsOut = numGlyphs + 1;\n    let dupFirstEntry = true;\n    if (numGlyphsOut > 0xffff) {\n      dupFirstEntry = false;\n      numGlyphsOut = numGlyphs;\n      warn(\"Not enough space in glyfs to duplicate first glyph.\");\n    }\n    let maxFunctionDefs = 0;\n    let maxSizeOfInstructions = 0;\n    if (version >= 0x00010000 && tables.maxp.length >= 32) {\n      font.pos += 8;\n      const maxZones = font.getUint16();\n      if (maxZones > 2) {\n        tables.maxp.data[14] = 0;\n        tables.maxp.data[15] = 2;\n      }\n      font.pos += 4;\n      maxFunctionDefs = font.getUint16();\n      font.pos += 4;\n      maxSizeOfInstructions = font.getUint16();\n    }\n    tables.maxp.data[4] = numGlyphsOut >> 8;\n    tables.maxp.data[5] = numGlyphsOut & 255;\n    const hintsValid = sanitizeTTPrograms(tables.fpgm, tables.prep, tables[\"cvt \"], maxFunctionDefs);\n    if (!hintsValid) {\n      delete tables.fpgm;\n      delete tables.prep;\n      delete tables[\"cvt \"];\n    }\n    sanitizeMetrics(font, tables.hhea, tables.hmtx, tables.head, numGlyphsOut, dupFirstEntry);\n    if (!tables.head) {\n      throw new FormatError('Required \"head\" table is not found');\n    }\n    sanitizeHead(tables.head, numGlyphs, isTrueType ? tables.loca.length : 0);\n    let missingGlyphs = Object.create(null);\n    if (isTrueType) {\n      const isGlyphLocationsLong = int16(tables.head.data[50], tables.head.data[51]);\n      const glyphsInfo = sanitizeGlyphLocations(tables.loca, tables.glyf, numGlyphs, isGlyphLocationsLong, hintsValid, dupFirstEntry, maxSizeOfInstructions);\n      missingGlyphs = glyphsInfo.missingGlyphs;\n      if (version >= 0x00010000 && tables.maxp.length >= 32) {\n        tables.maxp.data[26] = glyphsInfo.maxSizeOfInstructions >> 8;\n        tables.maxp.data[27] = glyphsInfo.maxSizeOfInstructions & 255;\n      }\n    }\n    if (!tables.hhea) {\n      throw new FormatError('Required \"hhea\" table is not found');\n    }\n    if (tables.hhea.data[10] === 0 && tables.hhea.data[11] === 0) {\n      tables.hhea.data[10] = 0xff;\n      tables.hhea.data[11] = 0xff;\n    }\n    const metricsOverride = {\n      unitsPerEm: int16(tables.head.data[18], tables.head.data[19]),\n      yMax: signedInt16(tables.head.data[42], tables.head.data[43]),\n      yMin: signedInt16(tables.head.data[38], tables.head.data[39]),\n      ascent: signedInt16(tables.hhea.data[4], tables.hhea.data[5]),\n      descent: signedInt16(tables.hhea.data[6], tables.hhea.data[7]),\n      lineGap: signedInt16(tables.hhea.data[8], tables.hhea.data[9])\n    };\n    this.ascent = metricsOverride.ascent / metricsOverride.unitsPerEm;\n    this.descent = metricsOverride.descent / metricsOverride.unitsPerEm;\n    this.lineGap = metricsOverride.lineGap / metricsOverride.unitsPerEm;\n    if (this.cssFontInfo?.lineHeight) {\n      this.lineHeight = this.cssFontInfo.metrics.lineHeight;\n      this.lineGap = this.cssFontInfo.metrics.lineGap;\n    } else {\n      this.lineHeight = this.ascent - this.descent + this.lineGap;\n    }\n    if (tables.post) {\n      readPostScriptTable(tables.post, properties, numGlyphs);\n    }\n    tables.post = {\n      tag: \"post\",\n      data: createPostTable(properties)\n    };\n    const charCodeToGlyphId = [];\n    function hasGlyph(glyphId) {\n      return !missingGlyphs[glyphId];\n    }\n    if (properties.composite) {\n      const cidToGidMap = properties.cidToGidMap || [];\n      const isCidToGidMapEmpty = cidToGidMap.length === 0;\n      properties.cMap.forEach(function (charCode, cid) {\n        if (typeof cid === \"string\") {\n          cid = convertCidString(charCode, cid, true);\n        }\n        if (cid > 0xffff) {\n          throw new FormatError(\"Max size of CID is 65,535\");\n        }\n        let glyphId = -1;\n        if (isCidToGidMapEmpty) {\n          glyphId = cid;\n        } else if (cidToGidMap[cid] !== undefined) {\n          glyphId = cidToGidMap[cid];\n        }\n        if (glyphId >= 0 && glyphId < numGlyphs && hasGlyph(glyphId)) {\n          charCodeToGlyphId[charCode] = glyphId;\n        }\n      });\n    } else {\n      const cmapTable = readCmapTable(tables.cmap, font, this.isSymbolicFont, properties.hasEncoding);\n      const cmapPlatformId = cmapTable.platformId;\n      const cmapEncodingId = cmapTable.encodingId;\n      const cmapMappings = cmapTable.mappings;\n      let baseEncoding = [],\n        forcePostTable = false;\n      if (properties.hasEncoding && (properties.baseEncodingName === \"MacRomanEncoding\" || properties.baseEncodingName === \"WinAnsiEncoding\")) {\n        baseEncoding = getEncoding(properties.baseEncodingName);\n      }\n      if (properties.hasEncoding && !this.isSymbolicFont && (cmapPlatformId === 3 && cmapEncodingId === 1 || cmapPlatformId === 1 && cmapEncodingId === 0)) {\n        const glyphsUnicodeMap = getGlyphsUnicode();\n        for (let charCode = 0; charCode < 256; charCode++) {\n          let glyphName;\n          if (this.differences[charCode] !== undefined) {\n            glyphName = this.differences[charCode];\n          } else if (baseEncoding.length && baseEncoding[charCode] !== \"\") {\n            glyphName = baseEncoding[charCode];\n          } else {\n            glyphName = StandardEncoding[charCode];\n          }\n          if (!glyphName) {\n            continue;\n          }\n          const standardGlyphName = recoverGlyphName(glyphName, glyphsUnicodeMap);\n          let unicodeOrCharCode;\n          if (cmapPlatformId === 3 && cmapEncodingId === 1) {\n            unicodeOrCharCode = glyphsUnicodeMap[standardGlyphName];\n          } else if (cmapPlatformId === 1 && cmapEncodingId === 0) {\n            unicodeOrCharCode = MacRomanEncoding.indexOf(standardGlyphName);\n          }\n          if (unicodeOrCharCode === undefined) {\n            if (!properties.glyphNames && properties.hasIncludedToUnicodeMap && !(this.toUnicode instanceof IdentityToUnicodeMap)) {\n              const unicode = this.toUnicode.get(charCode);\n              if (unicode) {\n                unicodeOrCharCode = unicode.codePointAt(0);\n              }\n            }\n            if (unicodeOrCharCode === undefined) {\n              continue;\n            }\n          }\n          for (const mapping of cmapMappings) {\n            if (mapping.charCode !== unicodeOrCharCode) {\n              continue;\n            }\n            charCodeToGlyphId[charCode] = mapping.glyphId;\n            break;\n          }\n        }\n      } else if (cmapPlatformId === 0) {\n        for (const mapping of cmapMappings) {\n          charCodeToGlyphId[mapping.charCode] = mapping.glyphId;\n        }\n        forcePostTable = true;\n      } else {\n        for (const mapping of cmapMappings) {\n          let charCode = mapping.charCode;\n          if (cmapPlatformId === 3 && charCode >= 0xf000 && charCode <= 0xf0ff) {\n            charCode &= 0xff;\n          }\n          charCodeToGlyphId[charCode] = mapping.glyphId;\n        }\n      }\n      if (properties.glyphNames && (baseEncoding.length || this.differences.length)) {\n        for (let i = 0; i < 256; ++i) {\n          if (!forcePostTable && charCodeToGlyphId[i] !== undefined) {\n            continue;\n          }\n          const glyphName = this.differences[i] || baseEncoding[i];\n          if (!glyphName) {\n            continue;\n          }\n          const glyphId = properties.glyphNames.indexOf(glyphName);\n          if (glyphId > 0 && hasGlyph(glyphId)) {\n            charCodeToGlyphId[i] = glyphId;\n          }\n        }\n      }\n    }\n    if (charCodeToGlyphId.length === 0) {\n      charCodeToGlyphId[0] = 0;\n    }\n    let glyphZeroId = numGlyphsOut - 1;\n    if (!dupFirstEntry) {\n      glyphZeroId = 0;\n    }\n    if (!properties.cssFontInfo) {\n      const newMapping = adjustMapping(charCodeToGlyphId, hasGlyph, glyphZeroId, this.toUnicode);\n      this.toFontChar = newMapping.toFontChar;\n      tables.cmap = {\n        tag: \"cmap\",\n        data: createCmapTable(newMapping.charCodeToGlyphId, newMapping.toUnicodeExtraMap, numGlyphsOut)\n      };\n      if (!tables[\"OS/2\"] || !validateOS2Table(tables[\"OS/2\"], font)) {\n        tables[\"OS/2\"] = {\n          tag: \"OS/2\",\n          data: createOS2Table(properties, newMapping.charCodeToGlyphId, metricsOverride)\n        };\n      }\n    }\n    if (!isTrueType) {\n      try {\n        cffFile = new Stream(tables[\"CFF \"].data);\n        const parser = new CFFParser(cffFile, properties, SEAC_ANALYSIS_ENABLED);\n        cff = parser.parse();\n        cff.duplicateFirstGlyph();\n        const compiler = new CFFCompiler(cff);\n        tables[\"CFF \"].data = compiler.compile();\n      } catch {\n        warn(\"Failed to compile font \" + properties.loadedName);\n      }\n    }\n    if (!tables.name) {\n      tables.name = {\n        tag: \"name\",\n        data: createNameTable(this.name)\n      };\n    } else {\n      const [namePrototype, nameRecords] = readNameTable(tables.name);\n      tables.name.data = createNameTable(name, namePrototype);\n      this.psName = namePrototype[0][6] || null;\n      if (!properties.composite) {\n        adjustTrueTypeToUnicode(properties, this.isSymbolicFont, nameRecords);\n      }\n    }\n    const builder = new OpenTypeFileBuilder(header.version);\n    for (const tableTag in tables) {\n      builder.addTable(tableTag, tables[tableTag].data);\n    }\n    return builder.toArray();\n  }\n  convert(fontName, font, properties) {\n    properties.fixedPitch = false;\n    if (properties.builtInEncoding) {\n      adjustType1ToUnicode(properties, properties.builtInEncoding);\n    }\n    let glyphZeroId = 1;\n    if (font instanceof CFFFont) {\n      glyphZeroId = font.numGlyphs - 1;\n    }\n    const mapping = font.getGlyphMapping(properties);\n    let newMapping = null;\n    let newCharCodeToGlyphId = mapping;\n    let toUnicodeExtraMap = null;\n    if (!properties.cssFontInfo) {\n      newMapping = adjustMapping(mapping, font.hasGlyphId.bind(font), glyphZeroId, this.toUnicode);\n      this.toFontChar = newMapping.toFontChar;\n      newCharCodeToGlyphId = newMapping.charCodeToGlyphId;\n      toUnicodeExtraMap = newMapping.toUnicodeExtraMap;\n    }\n    const numGlyphs = font.numGlyphs;\n    function getCharCodes(charCodeToGlyphId, glyphId) {\n      let charCodes = null;\n      for (const charCode in charCodeToGlyphId) {\n        if (glyphId === charCodeToGlyphId[charCode]) {\n          (charCodes ||= []).push(charCode | 0);\n        }\n      }\n      return charCodes;\n    }\n    function createCharCode(charCodeToGlyphId, glyphId) {\n      for (const charCode in charCodeToGlyphId) {\n        if (glyphId === charCodeToGlyphId[charCode]) {\n          return charCode | 0;\n        }\n      }\n      newMapping.charCodeToGlyphId[newMapping.nextAvailableFontCharCode] = glyphId;\n      return newMapping.nextAvailableFontCharCode++;\n    }\n    const seacs = font.seacs;\n    if (newMapping && SEAC_ANALYSIS_ENABLED && seacs?.length) {\n      const matrix = properties.fontMatrix || FONT_IDENTITY_MATRIX;\n      const charset = font.getCharset();\n      const seacMap = Object.create(null);\n      for (let glyphId in seacs) {\n        glyphId |= 0;\n        const seac = seacs[glyphId];\n        const baseGlyphName = StandardEncoding[seac[2]];\n        const accentGlyphName = StandardEncoding[seac[3]];\n        const baseGlyphId = charset.indexOf(baseGlyphName);\n        const accentGlyphId = charset.indexOf(accentGlyphName);\n        if (baseGlyphId < 0 || accentGlyphId < 0) {\n          continue;\n        }\n        const accentOffset = {\n          x: seac[0] * matrix[0] + seac[1] * matrix[2] + matrix[4],\n          y: seac[0] * matrix[1] + seac[1] * matrix[3] + matrix[5]\n        };\n        const charCodes = getCharCodes(mapping, glyphId);\n        if (!charCodes) {\n          continue;\n        }\n        for (const charCode of charCodes) {\n          const charCodeToGlyphId = newMapping.charCodeToGlyphId;\n          const baseFontCharCode = createCharCode(charCodeToGlyphId, baseGlyphId);\n          const accentFontCharCode = createCharCode(charCodeToGlyphId, accentGlyphId);\n          seacMap[charCode] = {\n            baseFontCharCode,\n            accentFontCharCode,\n            accentOffset\n          };\n        }\n      }\n      properties.seacMap = seacMap;\n    }\n    const unitsPerEm = 1 / (properties.fontMatrix || FONT_IDENTITY_MATRIX)[0];\n    const builder = new OpenTypeFileBuilder(\"\\x4F\\x54\\x54\\x4F\");\n    builder.addTable(\"CFF \", font.data);\n    builder.addTable(\"OS/2\", createOS2Table(properties, newCharCodeToGlyphId));\n    builder.addTable(\"cmap\", createCmapTable(newCharCodeToGlyphId, toUnicodeExtraMap, numGlyphs));\n    builder.addTable(\"head\", \"\\x00\\x01\\x00\\x00\" + \"\\x00\\x00\\x10\\x00\" + \"\\x00\\x00\\x00\\x00\" + \"\\x5F\\x0F\\x3C\\xF5\" + \"\\x00\\x00\" + safeString16(unitsPerEm) + \"\\x00\\x00\\x00\\x00\\x9e\\x0b\\x7e\\x27\" + \"\\x00\\x00\\x00\\x00\\x9e\\x0b\\x7e\\x27\" + \"\\x00\\x00\" + safeString16(properties.descent) + \"\\x0F\\xFF\" + safeString16(properties.ascent) + string16(properties.italicAngle ? 2 : 0) + \"\\x00\\x11\" + \"\\x00\\x00\" + \"\\x00\\x00\" + \"\\x00\\x00\");\n    builder.addTable(\"hhea\", \"\\x00\\x01\\x00\\x00\" + safeString16(properties.ascent) + safeString16(properties.descent) + \"\\x00\\x00\" + \"\\xFF\\xFF\" + \"\\x00\\x00\" + \"\\x00\\x00\" + \"\\x00\\x00\" + safeString16(properties.capHeight) + safeString16(Math.tan(properties.italicAngle) * properties.xHeight) + \"\\x00\\x00\" + \"\\x00\\x00\" + \"\\x00\\x00\" + \"\\x00\\x00\" + \"\\x00\\x00\" + \"\\x00\\x00\" + string16(numGlyphs));\n    builder.addTable(\"hmtx\", function fontFieldsHmtx() {\n      const charstrings = font.charstrings;\n      const cffWidths = font.cff ? font.cff.widths : null;\n      let hmtx = \"\\x00\\x00\\x00\\x00\";\n      for (let i = 1, ii = numGlyphs; i < ii; i++) {\n        let width = 0;\n        if (charstrings) {\n          const charstring = charstrings[i - 1];\n          width = \"width\" in charstring ? charstring.width : 0;\n        } else if (cffWidths) {\n          width = Math.ceil(cffWidths[i] || 0);\n        }\n        hmtx += string16(width) + string16(0);\n      }\n      return hmtx;\n    }());\n    builder.addTable(\"maxp\", \"\\x00\\x00\\x50\\x00\" + string16(numGlyphs));\n    builder.addTable(\"name\", createNameTable(fontName));\n    builder.addTable(\"post\", createPostTable(properties));\n    return builder.toArray();\n  }\n  get spaceWidth() {\n    const possibleSpaceReplacements = [\"space\", \"minus\", \"one\", \"i\", \"I\"];\n    let width;\n    for (const glyphName of possibleSpaceReplacements) {\n      if (glyphName in this.widths) {\n        width = this.widths[glyphName];\n        break;\n      }\n      const glyphsUnicodeMap = getGlyphsUnicode();\n      const glyphUnicode = glyphsUnicodeMap[glyphName];\n      let charcode = 0;\n      if (this.composite && this.cMap.contains(glyphUnicode)) {\n        charcode = this.cMap.lookup(glyphUnicode);\n        if (typeof charcode === \"string\") {\n          charcode = convertCidString(glyphUnicode, charcode);\n        }\n      }\n      if (!charcode && this.toUnicode) {\n        charcode = this.toUnicode.charCodeOf(glyphUnicode);\n      }\n      if (charcode <= 0) {\n        charcode = glyphUnicode;\n      }\n      width = this.widths[charcode];\n      if (width) {\n        break;\n      }\n    }\n    return shadow(this, \"spaceWidth\", width || this.defaultWidth);\n  }\n  _charToGlyph(charcode, isSpace = false) {\n    let glyph = this._glyphCache[charcode];\n    if (glyph?.isSpace === isSpace) {\n      return glyph;\n    }\n    let fontCharCode, width, operatorListId;\n    let widthCode = charcode;\n    if (this.cMap?.contains(charcode)) {\n      widthCode = this.cMap.lookup(charcode);\n      if (typeof widthCode === \"string\") {\n        widthCode = convertCidString(charcode, widthCode);\n      }\n    }\n    width = this.widths[widthCode];\n    if (typeof width !== \"number\") {\n      width = this.defaultWidth;\n    }\n    const vmetric = this.vmetrics?.[widthCode];\n    let unicode = this.toUnicode.get(charcode) || charcode;\n    if (typeof unicode === \"number\") {\n      unicode = String.fromCharCode(unicode);\n    }\n    let isInFont = this.toFontChar[charcode] !== undefined;\n    fontCharCode = this.toFontChar[charcode] || charcode;\n    if (this.missingFile) {\n      const glyphName = this.differences[charcode] || this.defaultEncoding?.[charcode] || String.fromCharCode(charcode);\n      if ((glyphName === \".notdef\" || glyphName === \"\") && this.type === \"Type1\") {\n        fontCharCode = 0x20;\n      }\n      fontCharCode = mapSpecialUnicodeValues(fontCharCode);\n    }\n    if (this.isType3Font) {\n      operatorListId = fontCharCode;\n    }\n    let accent = null;\n    if (this.seacMap?.[charcode]) {\n      isInFont = true;\n      const seac = this.seacMap[charcode];\n      fontCharCode = seac.baseFontCharCode;\n      accent = {\n        fontChar: String.fromCodePoint(seac.accentFontCharCode),\n        offset: seac.accentOffset\n      };\n    }\n    let fontChar = \"\";\n    if (typeof fontCharCode === \"number\") {\n      if (fontCharCode <= 0x10ffff) {\n        fontChar = String.fromCodePoint(fontCharCode);\n      } else {\n        warn(`charToGlyph - invalid fontCharCode: ${fontCharCode}`);\n      }\n    }\n    glyph = new fonts_Glyph(charcode, fontChar, unicode, accent, width, vmetric, operatorListId, isSpace, isInFont);\n    return this._glyphCache[charcode] = glyph;\n  }\n  charsToGlyphs(chars) {\n    let glyphs = this._charsCache[chars];\n    if (glyphs) {\n      return glyphs;\n    }\n    glyphs = [];\n    if (this.cMap) {\n      const c = Object.create(null),\n        ii = chars.length;\n      let i = 0;\n      while (i < ii) {\n        this.cMap.readCharCode(chars, i, c);\n        const {\n          charcode,\n          length\n        } = c;\n        i += length;\n        const glyph = this._charToGlyph(charcode, length === 1 && chars.charCodeAt(i - 1) === 0x20);\n        glyphs.push(glyph);\n      }\n    } else {\n      for (let i = 0, ii = chars.length; i < ii; ++i) {\n        const charcode = chars.charCodeAt(i);\n        const glyph = this._charToGlyph(charcode, charcode === 0x20);\n        glyphs.push(glyph);\n      }\n    }\n    return this._charsCache[chars] = glyphs;\n  }\n  getCharPositions(chars) {\n    const positions = [];\n    if (this.cMap) {\n      const c = Object.create(null);\n      let i = 0;\n      while (i < chars.length) {\n        this.cMap.readCharCode(chars, i, c);\n        const length = c.length;\n        positions.push([i, i + length]);\n        i += length;\n      }\n    } else {\n      for (let i = 0, ii = chars.length; i < ii; ++i) {\n        positions.push([i, i + 1]);\n      }\n    }\n    return positions;\n  }\n  get glyphCacheValues() {\n    return Object.values(this._glyphCache);\n  }\n  encodeString(str) {\n    const buffers = [];\n    const currentBuf = [];\n    const hasCurrentBufErrors = () => buffers.length % 2 === 1;\n    const getCharCode = this.toUnicode instanceof IdentityToUnicodeMap ? unicode => this.toUnicode.charCodeOf(unicode) : unicode => this.toUnicode.charCodeOf(String.fromCodePoint(unicode));\n    for (let i = 0, ii = str.length; i < ii; i++) {\n      const unicode = str.codePointAt(i);\n      if (unicode > 0xd7ff && (unicode < 0xe000 || unicode > 0xfffd)) {\n        i++;\n      }\n      if (this.toUnicode) {\n        const charCode = getCharCode(unicode);\n        if (charCode !== -1) {\n          if (hasCurrentBufErrors()) {\n            buffers.push(currentBuf.join(\"\"));\n            currentBuf.length = 0;\n          }\n          const charCodeLength = this.cMap ? this.cMap.getCharCodeLength(charCode) : 1;\n          for (let j = charCodeLength - 1; j >= 0; j--) {\n            currentBuf.push(String.fromCharCode(charCode >> 8 * j & 0xff));\n          }\n          continue;\n        }\n      }\n      if (!hasCurrentBufErrors()) {\n        buffers.push(currentBuf.join(\"\"));\n        currentBuf.length = 0;\n      }\n      currentBuf.push(String.fromCodePoint(unicode));\n    }\n    buffers.push(currentBuf.join(\"\"));\n    return buffers;\n  }\n}\nclass ErrorFont {\n  constructor(error) {\n    this.error = error;\n    this.loadedName = \"g_font_error\";\n    this.missingFile = true;\n  }\n  charsToGlyphs() {\n    return [];\n  }\n  encodeString(chars) {\n    return [chars];\n  }\n  exportData(extraProperties = false) {\n    return {\n      error: this.error\n    };\n  }\n}\n\n;// ./src/core/pattern.js\n\n\n\n\nconst ShadingType = {\n  FUNCTION_BASED: 1,\n  AXIAL: 2,\n  RADIAL: 3,\n  FREE_FORM_MESH: 4,\n  LATTICE_FORM_MESH: 5,\n  COONS_PATCH_MESH: 6,\n  TENSOR_PATCH_MESH: 7\n};\nclass Pattern {\n  constructor() {\n    unreachable(\"Cannot initialize Pattern.\");\n  }\n  static parseShading(shading, xref, res, pdfFunctionFactory, localColorSpaceCache) {\n    const dict = shading instanceof BaseStream ? shading.dict : shading;\n    const type = dict.get(\"ShadingType\");\n    try {\n      switch (type) {\n        case ShadingType.AXIAL:\n        case ShadingType.RADIAL:\n          return new RadialAxialShading(dict, xref, res, pdfFunctionFactory, localColorSpaceCache);\n        case ShadingType.FREE_FORM_MESH:\n        case ShadingType.LATTICE_FORM_MESH:\n        case ShadingType.COONS_PATCH_MESH:\n        case ShadingType.TENSOR_PATCH_MESH:\n          return new MeshShading(shading, xref, res, pdfFunctionFactory, localColorSpaceCache);\n        default:\n          throw new FormatError(\"Unsupported ShadingType: \" + type);\n      }\n    } catch (ex) {\n      if (ex instanceof MissingDataException) {\n        throw ex;\n      }\n      warn(ex);\n      return new DummyShading();\n    }\n  }\n}\nclass BaseShading {\n  static SMALL_NUMBER = 1e-6;\n  constructor() {\n    if (this.constructor === BaseShading) {\n      unreachable(\"Cannot initialize BaseShading.\");\n    }\n  }\n  getIR() {\n    unreachable(\"Abstract method `getIR` called.\");\n  }\n}\nclass RadialAxialShading extends BaseShading {\n  constructor(dict, xref, resources, pdfFunctionFactory, localColorSpaceCache) {\n    super();\n    this.coordsArr = dict.getArray(\"Coords\");\n    this.shadingType = dict.get(\"ShadingType\");\n    const cs = ColorSpace.parse({\n      cs: dict.getRaw(\"CS\") || dict.getRaw(\"ColorSpace\"),\n      xref,\n      resources,\n      pdfFunctionFactory,\n      localColorSpaceCache\n    });\n    const bbox = dict.getArray(\"BBox\");\n    this.bbox = Array.isArray(bbox) && bbox.length === 4 ? Util.normalizeRect(bbox) : null;\n    let t0 = 0.0,\n      t1 = 1.0;\n    if (dict.has(\"Domain\")) {\n      const domainArr = dict.getArray(\"Domain\");\n      t0 = domainArr[0];\n      t1 = domainArr[1];\n    }\n    let extendStart = false,\n      extendEnd = false;\n    if (dict.has(\"Extend\")) {\n      const extendArr = dict.getArray(\"Extend\");\n      extendStart = extendArr[0];\n      extendEnd = extendArr[1];\n    }\n    if (this.shadingType === ShadingType.RADIAL && (!extendStart || !extendEnd)) {\n      const [x1, y1, r1, x2, y2, r2] = this.coordsArr;\n      const distance = Math.hypot(x1 - x2, y1 - y2);\n      if (r1 <= r2 + distance && r2 <= r1 + distance) {\n        warn(\"Unsupported radial gradient.\");\n      }\n    }\n    this.extendStart = extendStart;\n    this.extendEnd = extendEnd;\n    const fnObj = dict.getRaw(\"Function\");\n    const fn = pdfFunctionFactory.createFromArray(fnObj);\n    const NUMBER_OF_SAMPLES = 840;\n    const step = (t1 - t0) / NUMBER_OF_SAMPLES;\n    const colorStops = this.colorStops = [];\n    if (t0 >= t1 || step <= 0) {\n      info(\"Bad shading domain.\");\n      return;\n    }\n    const color = new Float32Array(cs.numComps),\n      ratio = new Float32Array(1);\n    let rgbColor;\n    let iBase = 0;\n    ratio[0] = t0;\n    fn(ratio, 0, color, 0);\n    let rgbBase = cs.getRgb(color, 0);\n    const cssColorBase = Util.makeHexColor(rgbBase[0], rgbBase[1], rgbBase[2]);\n    colorStops.push([0, cssColorBase]);\n    let iPrev = 1;\n    ratio[0] = t0 + step;\n    fn(ratio, 0, color, 0);\n    let rgbPrev = cs.getRgb(color, 0);\n    let maxSlopeR = rgbPrev[0] - rgbBase[0] + 1;\n    let maxSlopeG = rgbPrev[1] - rgbBase[1] + 1;\n    let maxSlopeB = rgbPrev[2] - rgbBase[2] + 1;\n    let minSlopeR = rgbPrev[0] - rgbBase[0] - 1;\n    let minSlopeG = rgbPrev[1] - rgbBase[1] - 1;\n    let minSlopeB = rgbPrev[2] - rgbBase[2] - 1;\n    for (let i = 2; i < NUMBER_OF_SAMPLES; i++) {\n      ratio[0] = t0 + i * step;\n      fn(ratio, 0, color, 0);\n      rgbColor = cs.getRgb(color, 0);\n      const run = i - iBase;\n      maxSlopeR = Math.min(maxSlopeR, (rgbColor[0] - rgbBase[0] + 1) / run);\n      maxSlopeG = Math.min(maxSlopeG, (rgbColor[1] - rgbBase[1] + 1) / run);\n      maxSlopeB = Math.min(maxSlopeB, (rgbColor[2] - rgbBase[2] + 1) / run);\n      minSlopeR = Math.max(minSlopeR, (rgbColor[0] - rgbBase[0] - 1) / run);\n      minSlopeG = Math.max(minSlopeG, (rgbColor[1] - rgbBase[1] - 1) / run);\n      minSlopeB = Math.max(minSlopeB, (rgbColor[2] - rgbBase[2] - 1) / run);\n      const slopesExist = minSlopeR <= maxSlopeR && minSlopeG <= maxSlopeG && minSlopeB <= maxSlopeB;\n      if (!slopesExist) {\n        const cssColor = Util.makeHexColor(rgbPrev[0], rgbPrev[1], rgbPrev[2]);\n        colorStops.push([iPrev / NUMBER_OF_SAMPLES, cssColor]);\n        maxSlopeR = rgbColor[0] - rgbPrev[0] + 1;\n        maxSlopeG = rgbColor[1] - rgbPrev[1] + 1;\n        maxSlopeB = rgbColor[2] - rgbPrev[2] + 1;\n        minSlopeR = rgbColor[0] - rgbPrev[0] - 1;\n        minSlopeG = rgbColor[1] - rgbPrev[1] - 1;\n        minSlopeB = rgbColor[2] - rgbPrev[2] - 1;\n        iBase = iPrev;\n        rgbBase = rgbPrev;\n      }\n      iPrev = i;\n      rgbPrev = rgbColor;\n    }\n    const cssColor = Util.makeHexColor(rgbPrev[0], rgbPrev[1], rgbPrev[2]);\n    colorStops.push([1, cssColor]);\n    let background = \"transparent\";\n    if (dict.has(\"Background\")) {\n      rgbColor = cs.getRgb(dict.get(\"Background\"), 0);\n      background = Util.makeHexColor(rgbColor[0], rgbColor[1], rgbColor[2]);\n    }\n    if (!extendStart) {\n      colorStops.unshift([0, background]);\n      colorStops[1][0] += BaseShading.SMALL_NUMBER;\n    }\n    if (!extendEnd) {\n      colorStops.at(-1)[0] -= BaseShading.SMALL_NUMBER;\n      colorStops.push([1, background]);\n    }\n    this.colorStops = colorStops;\n  }\n  getIR() {\n    const coordsArr = this.coordsArr;\n    const shadingType = this.shadingType;\n    let type, p0, p1, r0, r1;\n    if (shadingType === ShadingType.AXIAL) {\n      p0 = [coordsArr[0], coordsArr[1]];\n      p1 = [coordsArr[2], coordsArr[3]];\n      r0 = null;\n      r1 = null;\n      type = \"axial\";\n    } else if (shadingType === ShadingType.RADIAL) {\n      p0 = [coordsArr[0], coordsArr[1]];\n      p1 = [coordsArr[3], coordsArr[4]];\n      r0 = coordsArr[2];\n      r1 = coordsArr[5];\n      type = \"radial\";\n    } else {\n      unreachable(`getPattern type unknown: ${shadingType}`);\n    }\n    return [\"RadialAxial\", type, this.bbox, this.colorStops, p0, p1, r0, r1];\n  }\n}\nclass MeshStreamReader {\n  constructor(stream, context) {\n    this.stream = stream;\n    this.context = context;\n    this.buffer = 0;\n    this.bufferLength = 0;\n    const numComps = context.numComps;\n    this.tmpCompsBuf = new Float32Array(numComps);\n    const csNumComps = context.colorSpace.numComps;\n    this.tmpCsCompsBuf = context.colorFn ? new Float32Array(csNumComps) : this.tmpCompsBuf;\n  }\n  get hasData() {\n    if (this.stream.end) {\n      return this.stream.pos < this.stream.end;\n    }\n    if (this.bufferLength > 0) {\n      return true;\n    }\n    const nextByte = this.stream.getByte();\n    if (nextByte < 0) {\n      return false;\n    }\n    this.buffer = nextByte;\n    this.bufferLength = 8;\n    return true;\n  }\n  readBits(n) {\n    let buffer = this.buffer;\n    let bufferLength = this.bufferLength;\n    if (n === 32) {\n      if (bufferLength === 0) {\n        return (this.stream.getByte() << 24 | this.stream.getByte() << 16 | this.stream.getByte() << 8 | this.stream.getByte()) >>> 0;\n      }\n      buffer = buffer << 24 | this.stream.getByte() << 16 | this.stream.getByte() << 8 | this.stream.getByte();\n      const nextByte = this.stream.getByte();\n      this.buffer = nextByte & (1 << bufferLength) - 1;\n      return (buffer << 8 - bufferLength | (nextByte & 0xff) >> bufferLength) >>> 0;\n    }\n    if (n === 8 && bufferLength === 0) {\n      return this.stream.getByte();\n    }\n    while (bufferLength < n) {\n      buffer = buffer << 8 | this.stream.getByte();\n      bufferLength += 8;\n    }\n    bufferLength -= n;\n    this.bufferLength = bufferLength;\n    this.buffer = buffer & (1 << bufferLength) - 1;\n    return buffer >> bufferLength;\n  }\n  align() {\n    this.buffer = 0;\n    this.bufferLength = 0;\n  }\n  readFlag() {\n    return this.readBits(this.context.bitsPerFlag);\n  }\n  readCoordinate() {\n    const bitsPerCoordinate = this.context.bitsPerCoordinate;\n    const xi = this.readBits(bitsPerCoordinate);\n    const yi = this.readBits(bitsPerCoordinate);\n    const decode = this.context.decode;\n    const scale = bitsPerCoordinate < 32 ? 1 / ((1 << bitsPerCoordinate) - 1) : 2.3283064365386963e-10;\n    return [xi * scale * (decode[1] - decode[0]) + decode[0], yi * scale * (decode[3] - decode[2]) + decode[2]];\n  }\n  readComponents() {\n    const numComps = this.context.numComps;\n    const bitsPerComponent = this.context.bitsPerComponent;\n    const scale = bitsPerComponent < 32 ? 1 / ((1 << bitsPerComponent) - 1) : 2.3283064365386963e-10;\n    const decode = this.context.decode;\n    const components = this.tmpCompsBuf;\n    for (let i = 0, j = 4; i < numComps; i++, j += 2) {\n      const ci = this.readBits(bitsPerComponent);\n      components[i] = ci * scale * (decode[j + 1] - decode[j]) + decode[j];\n    }\n    const color = this.tmpCsCompsBuf;\n    if (this.context.colorFn) {\n      this.context.colorFn(components, 0, color, 0);\n    }\n    return this.context.colorSpace.getRgb(color, 0);\n  }\n}\nlet bCache = Object.create(null);\nfunction buildB(count) {\n  const lut = [];\n  for (let i = 0; i <= count; i++) {\n    const t = i / count,\n      t_ = 1 - t;\n    lut.push(new Float32Array([t_ ** 3, 3 * t * t_ ** 2, 3 * t ** 2 * t_, t ** 3]));\n  }\n  return lut;\n}\nfunction getB(count) {\n  return bCache[count] ||= buildB(count);\n}\nfunction clearPatternCaches() {\n  bCache = Object.create(null);\n}\nclass MeshShading extends BaseShading {\n  static MIN_SPLIT_PATCH_CHUNKS_AMOUNT = 3;\n  static MAX_SPLIT_PATCH_CHUNKS_AMOUNT = 20;\n  static TRIANGLE_DENSITY = 20;\n  constructor(stream, xref, resources, pdfFunctionFactory, localColorSpaceCache) {\n    super();\n    if (!(stream instanceof BaseStream)) {\n      throw new FormatError(\"Mesh data is not a stream\");\n    }\n    const dict = stream.dict;\n    this.shadingType = dict.get(\"ShadingType\");\n    const bbox = dict.getArray(\"BBox\");\n    this.bbox = Array.isArray(bbox) && bbox.length === 4 ? Util.normalizeRect(bbox) : null;\n    const cs = ColorSpace.parse({\n      cs: dict.getRaw(\"CS\") || dict.getRaw(\"ColorSpace\"),\n      xref,\n      resources,\n      pdfFunctionFactory,\n      localColorSpaceCache\n    });\n    this.background = dict.has(\"Background\") ? cs.getRgb(dict.get(\"Background\"), 0) : null;\n    const fnObj = dict.getRaw(\"Function\");\n    const fn = fnObj ? pdfFunctionFactory.createFromArray(fnObj) : null;\n    this.coords = [];\n    this.colors = [];\n    this.figures = [];\n    const decodeContext = {\n      bitsPerCoordinate: dict.get(\"BitsPerCoordinate\"),\n      bitsPerComponent: dict.get(\"BitsPerComponent\"),\n      bitsPerFlag: dict.get(\"BitsPerFlag\"),\n      decode: dict.getArray(\"Decode\"),\n      colorFn: fn,\n      colorSpace: cs,\n      numComps: fn ? 1 : cs.numComps\n    };\n    const reader = new MeshStreamReader(stream, decodeContext);\n    let patchMesh = false;\n    switch (this.shadingType) {\n      case ShadingType.FREE_FORM_MESH:\n        this._decodeType4Shading(reader);\n        break;\n      case ShadingType.LATTICE_FORM_MESH:\n        const verticesPerRow = dict.get(\"VerticesPerRow\") | 0;\n        if (verticesPerRow < 2) {\n          throw new FormatError(\"Invalid VerticesPerRow\");\n        }\n        this._decodeType5Shading(reader, verticesPerRow);\n        break;\n      case ShadingType.COONS_PATCH_MESH:\n        this._decodeType6Shading(reader);\n        patchMesh = true;\n        break;\n      case ShadingType.TENSOR_PATCH_MESH:\n        this._decodeType7Shading(reader);\n        patchMesh = true;\n        break;\n      default:\n        unreachable(\"Unsupported mesh type.\");\n        break;\n    }\n    if (patchMesh) {\n      this._updateBounds();\n      for (let i = 0, ii = this.figures.length; i < ii; i++) {\n        this._buildFigureFromPatch(i);\n      }\n    }\n    this._updateBounds();\n    this._packData();\n  }\n  _decodeType4Shading(reader) {\n    const coords = this.coords;\n    const colors = this.colors;\n    const operators = [];\n    const ps = [];\n    let verticesLeft = 0;\n    while (reader.hasData) {\n      const f = reader.readFlag();\n      const coord = reader.readCoordinate();\n      const color = reader.readComponents();\n      if (verticesLeft === 0) {\n        if (!(0 <= f && f <= 2)) {\n          throw new FormatError(\"Unknown type4 flag\");\n        }\n        switch (f) {\n          case 0:\n            verticesLeft = 3;\n            break;\n          case 1:\n            ps.push(ps.at(-2), ps.at(-1));\n            verticesLeft = 1;\n            break;\n          case 2:\n            ps.push(ps.at(-3), ps.at(-1));\n            verticesLeft = 1;\n            break;\n        }\n        operators.push(f);\n      }\n      ps.push(coords.length);\n      coords.push(coord);\n      colors.push(color);\n      verticesLeft--;\n      reader.align();\n    }\n    this.figures.push({\n      type: \"triangles\",\n      coords: new Int32Array(ps),\n      colors: new Int32Array(ps)\n    });\n  }\n  _decodeType5Shading(reader, verticesPerRow) {\n    const coords = this.coords;\n    const colors = this.colors;\n    const ps = [];\n    while (reader.hasData) {\n      const coord = reader.readCoordinate();\n      const color = reader.readComponents();\n      ps.push(coords.length);\n      coords.push(coord);\n      colors.push(color);\n    }\n    this.figures.push({\n      type: \"lattice\",\n      coords: new Int32Array(ps),\n      colors: new Int32Array(ps),\n      verticesPerRow\n    });\n  }\n  _decodeType6Shading(reader) {\n    const coords = this.coords;\n    const colors = this.colors;\n    const ps = new Int32Array(16);\n    const cs = new Int32Array(4);\n    while (reader.hasData) {\n      const f = reader.readFlag();\n      if (!(0 <= f && f <= 3)) {\n        throw new FormatError(\"Unknown type6 flag\");\n      }\n      const pi = coords.length;\n      for (let i = 0, ii = f !== 0 ? 8 : 12; i < ii; i++) {\n        coords.push(reader.readCoordinate());\n      }\n      const ci = colors.length;\n      for (let i = 0, ii = f !== 0 ? 2 : 4; i < ii; i++) {\n        colors.push(reader.readComponents());\n      }\n      let tmp1, tmp2, tmp3, tmp4;\n      switch (f) {\n        case 0:\n          ps[12] = pi + 3;\n          ps[13] = pi + 4;\n          ps[14] = pi + 5;\n          ps[15] = pi + 6;\n          ps[8] = pi + 2;\n          ps[11] = pi + 7;\n          ps[4] = pi + 1;\n          ps[7] = pi + 8;\n          ps[0] = pi;\n          ps[1] = pi + 11;\n          ps[2] = pi + 10;\n          ps[3] = pi + 9;\n          cs[2] = ci + 1;\n          cs[3] = ci + 2;\n          cs[0] = ci;\n          cs[1] = ci + 3;\n          break;\n        case 1:\n          tmp1 = ps[12];\n          tmp2 = ps[13];\n          tmp3 = ps[14];\n          tmp4 = ps[15];\n          ps[12] = tmp4;\n          ps[13] = pi + 0;\n          ps[14] = pi + 1;\n          ps[15] = pi + 2;\n          ps[8] = tmp3;\n          ps[11] = pi + 3;\n          ps[4] = tmp2;\n          ps[7] = pi + 4;\n          ps[0] = tmp1;\n          ps[1] = pi + 7;\n          ps[2] = pi + 6;\n          ps[3] = pi + 5;\n          tmp1 = cs[2];\n          tmp2 = cs[3];\n          cs[2] = tmp2;\n          cs[3] = ci;\n          cs[0] = tmp1;\n          cs[1] = ci + 1;\n          break;\n        case 2:\n          tmp1 = ps[15];\n          tmp2 = ps[11];\n          ps[12] = ps[3];\n          ps[13] = pi + 0;\n          ps[14] = pi + 1;\n          ps[15] = pi + 2;\n          ps[8] = ps[7];\n          ps[11] = pi + 3;\n          ps[4] = tmp2;\n          ps[7] = pi + 4;\n          ps[0] = tmp1;\n          ps[1] = pi + 7;\n          ps[2] = pi + 6;\n          ps[3] = pi + 5;\n          tmp1 = cs[3];\n          cs[2] = cs[1];\n          cs[3] = ci;\n          cs[0] = tmp1;\n          cs[1] = ci + 1;\n          break;\n        case 3:\n          ps[12] = ps[0];\n          ps[13] = pi + 0;\n          ps[14] = pi + 1;\n          ps[15] = pi + 2;\n          ps[8] = ps[1];\n          ps[11] = pi + 3;\n          ps[4] = ps[2];\n          ps[7] = pi + 4;\n          ps[0] = ps[3];\n          ps[1] = pi + 7;\n          ps[2] = pi + 6;\n          ps[3] = pi + 5;\n          cs[2] = cs[0];\n          cs[3] = ci;\n          cs[0] = cs[1];\n          cs[1] = ci + 1;\n          break;\n      }\n      ps[5] = coords.length;\n      coords.push([(-4 * coords[ps[0]][0] - coords[ps[15]][0] + 6 * (coords[ps[4]][0] + coords[ps[1]][0]) - 2 * (coords[ps[12]][0] + coords[ps[3]][0]) + 3 * (coords[ps[13]][0] + coords[ps[7]][0])) / 9, (-4 * coords[ps[0]][1] - coords[ps[15]][1] + 6 * (coords[ps[4]][1] + coords[ps[1]][1]) - 2 * (coords[ps[12]][1] + coords[ps[3]][1]) + 3 * (coords[ps[13]][1] + coords[ps[7]][1])) / 9]);\n      ps[6] = coords.length;\n      coords.push([(-4 * coords[ps[3]][0] - coords[ps[12]][0] + 6 * (coords[ps[2]][0] + coords[ps[7]][0]) - 2 * (coords[ps[0]][0] + coords[ps[15]][0]) + 3 * (coords[ps[4]][0] + coords[ps[14]][0])) / 9, (-4 * coords[ps[3]][1] - coords[ps[12]][1] + 6 * (coords[ps[2]][1] + coords[ps[7]][1]) - 2 * (coords[ps[0]][1] + coords[ps[15]][1]) + 3 * (coords[ps[4]][1] + coords[ps[14]][1])) / 9]);\n      ps[9] = coords.length;\n      coords.push([(-4 * coords[ps[12]][0] - coords[ps[3]][0] + 6 * (coords[ps[8]][0] + coords[ps[13]][0]) - 2 * (coords[ps[0]][0] + coords[ps[15]][0]) + 3 * (coords[ps[11]][0] + coords[ps[1]][0])) / 9, (-4 * coords[ps[12]][1] - coords[ps[3]][1] + 6 * (coords[ps[8]][1] + coords[ps[13]][1]) - 2 * (coords[ps[0]][1] + coords[ps[15]][1]) + 3 * (coords[ps[11]][1] + coords[ps[1]][1])) / 9]);\n      ps[10] = coords.length;\n      coords.push([(-4 * coords[ps[15]][0] - coords[ps[0]][0] + 6 * (coords[ps[11]][0] + coords[ps[14]][0]) - 2 * (coords[ps[12]][0] + coords[ps[3]][0]) + 3 * (coords[ps[2]][0] + coords[ps[8]][0])) / 9, (-4 * coords[ps[15]][1] - coords[ps[0]][1] + 6 * (coords[ps[11]][1] + coords[ps[14]][1]) - 2 * (coords[ps[12]][1] + coords[ps[3]][1]) + 3 * (coords[ps[2]][1] + coords[ps[8]][1])) / 9]);\n      this.figures.push({\n        type: \"patch\",\n        coords: new Int32Array(ps),\n        colors: new Int32Array(cs)\n      });\n    }\n  }\n  _decodeType7Shading(reader) {\n    const coords = this.coords;\n    const colors = this.colors;\n    const ps = new Int32Array(16);\n    const cs = new Int32Array(4);\n    while (reader.hasData) {\n      const f = reader.readFlag();\n      if (!(0 <= f && f <= 3)) {\n        throw new FormatError(\"Unknown type7 flag\");\n      }\n      const pi = coords.length;\n      for (let i = 0, ii = f !== 0 ? 12 : 16; i < ii; i++) {\n        coords.push(reader.readCoordinate());\n      }\n      const ci = colors.length;\n      for (let i = 0, ii = f !== 0 ? 2 : 4; i < ii; i++) {\n        colors.push(reader.readComponents());\n      }\n      let tmp1, tmp2, tmp3, tmp4;\n      switch (f) {\n        case 0:\n          ps[12] = pi + 3;\n          ps[13] = pi + 4;\n          ps[14] = pi + 5;\n          ps[15] = pi + 6;\n          ps[8] = pi + 2;\n          ps[9] = pi + 13;\n          ps[10] = pi + 14;\n          ps[11] = pi + 7;\n          ps[4] = pi + 1;\n          ps[5] = pi + 12;\n          ps[6] = pi + 15;\n          ps[7] = pi + 8;\n          ps[0] = pi;\n          ps[1] = pi + 11;\n          ps[2] = pi + 10;\n          ps[3] = pi + 9;\n          cs[2] = ci + 1;\n          cs[3] = ci + 2;\n          cs[0] = ci;\n          cs[1] = ci + 3;\n          break;\n        case 1:\n          tmp1 = ps[12];\n          tmp2 = ps[13];\n          tmp3 = ps[14];\n          tmp4 = ps[15];\n          ps[12] = tmp4;\n          ps[13] = pi + 0;\n          ps[14] = pi + 1;\n          ps[15] = pi + 2;\n          ps[8] = tmp3;\n          ps[9] = pi + 9;\n          ps[10] = pi + 10;\n          ps[11] = pi + 3;\n          ps[4] = tmp2;\n          ps[5] = pi + 8;\n          ps[6] = pi + 11;\n          ps[7] = pi + 4;\n          ps[0] = tmp1;\n          ps[1] = pi + 7;\n          ps[2] = pi + 6;\n          ps[3] = pi + 5;\n          tmp1 = cs[2];\n          tmp2 = cs[3];\n          cs[2] = tmp2;\n          cs[3] = ci;\n          cs[0] = tmp1;\n          cs[1] = ci + 1;\n          break;\n        case 2:\n          tmp1 = ps[15];\n          tmp2 = ps[11];\n          ps[12] = ps[3];\n          ps[13] = pi + 0;\n          ps[14] = pi + 1;\n          ps[15] = pi + 2;\n          ps[8] = ps[7];\n          ps[9] = pi + 9;\n          ps[10] = pi + 10;\n          ps[11] = pi + 3;\n          ps[4] = tmp2;\n          ps[5] = pi + 8;\n          ps[6] = pi + 11;\n          ps[7] = pi + 4;\n          ps[0] = tmp1;\n          ps[1] = pi + 7;\n          ps[2] = pi + 6;\n          ps[3] = pi + 5;\n          tmp1 = cs[3];\n          cs[2] = cs[1];\n          cs[3] = ci;\n          cs[0] = tmp1;\n          cs[1] = ci + 1;\n          break;\n        case 3:\n          ps[12] = ps[0];\n          ps[13] = pi + 0;\n          ps[14] = pi + 1;\n          ps[15] = pi + 2;\n          ps[8] = ps[1];\n          ps[9] = pi + 9;\n          ps[10] = pi + 10;\n          ps[11] = pi + 3;\n          ps[4] = ps[2];\n          ps[5] = pi + 8;\n          ps[6] = pi + 11;\n          ps[7] = pi + 4;\n          ps[0] = ps[3];\n          ps[1] = pi + 7;\n          ps[2] = pi + 6;\n          ps[3] = pi + 5;\n          cs[2] = cs[0];\n          cs[3] = ci;\n          cs[0] = cs[1];\n          cs[1] = ci + 1;\n          break;\n      }\n      this.figures.push({\n        type: \"patch\",\n        coords: new Int32Array(ps),\n        colors: new Int32Array(cs)\n      });\n    }\n  }\n  _buildFigureFromPatch(index) {\n    const figure = this.figures[index];\n    assert(figure.type === \"patch\", \"Unexpected patch mesh figure\");\n    const coords = this.coords,\n      colors = this.colors;\n    const pi = figure.coords;\n    const ci = figure.colors;\n    const figureMinX = Math.min(coords[pi[0]][0], coords[pi[3]][0], coords[pi[12]][0], coords[pi[15]][0]);\n    const figureMinY = Math.min(coords[pi[0]][1], coords[pi[3]][1], coords[pi[12]][1], coords[pi[15]][1]);\n    const figureMaxX = Math.max(coords[pi[0]][0], coords[pi[3]][0], coords[pi[12]][0], coords[pi[15]][0]);\n    const figureMaxY = Math.max(coords[pi[0]][1], coords[pi[3]][1], coords[pi[12]][1], coords[pi[15]][1]);\n    let splitXBy = Math.ceil((figureMaxX - figureMinX) * MeshShading.TRIANGLE_DENSITY / (this.bounds[2] - this.bounds[0]));\n    splitXBy = Math.max(MeshShading.MIN_SPLIT_PATCH_CHUNKS_AMOUNT, Math.min(MeshShading.MAX_SPLIT_PATCH_CHUNKS_AMOUNT, splitXBy));\n    let splitYBy = Math.ceil((figureMaxY - figureMinY) * MeshShading.TRIANGLE_DENSITY / (this.bounds[3] - this.bounds[1]));\n    splitYBy = Math.max(MeshShading.MIN_SPLIT_PATCH_CHUNKS_AMOUNT, Math.min(MeshShading.MAX_SPLIT_PATCH_CHUNKS_AMOUNT, splitYBy));\n    const verticesPerRow = splitXBy + 1;\n    const figureCoords = new Int32Array((splitYBy + 1) * verticesPerRow);\n    const figureColors = new Int32Array((splitYBy + 1) * verticesPerRow);\n    let k = 0;\n    const cl = new Uint8Array(3),\n      cr = new Uint8Array(3);\n    const c0 = colors[ci[0]],\n      c1 = colors[ci[1]],\n      c2 = colors[ci[2]],\n      c3 = colors[ci[3]];\n    const bRow = getB(splitYBy),\n      bCol = getB(splitXBy);\n    for (let row = 0; row <= splitYBy; row++) {\n      cl[0] = (c0[0] * (splitYBy - row) + c2[0] * row) / splitYBy | 0;\n      cl[1] = (c0[1] * (splitYBy - row) + c2[1] * row) / splitYBy | 0;\n      cl[2] = (c0[2] * (splitYBy - row) + c2[2] * row) / splitYBy | 0;\n      cr[0] = (c1[0] * (splitYBy - row) + c3[0] * row) / splitYBy | 0;\n      cr[1] = (c1[1] * (splitYBy - row) + c3[1] * row) / splitYBy | 0;\n      cr[2] = (c1[2] * (splitYBy - row) + c3[2] * row) / splitYBy | 0;\n      for (let col = 0; col <= splitXBy; col++, k++) {\n        if ((row === 0 || row === splitYBy) && (col === 0 || col === splitXBy)) {\n          continue;\n        }\n        let x = 0,\n          y = 0;\n        let q = 0;\n        for (let i = 0; i <= 3; i++) {\n          for (let j = 0; j <= 3; j++, q++) {\n            const m = bRow[row][i] * bCol[col][j];\n            x += coords[pi[q]][0] * m;\n            y += coords[pi[q]][1] * m;\n          }\n        }\n        figureCoords[k] = coords.length;\n        coords.push([x, y]);\n        figureColors[k] = colors.length;\n        const newColor = new Uint8Array(3);\n        newColor[0] = (cl[0] * (splitXBy - col) + cr[0] * col) / splitXBy | 0;\n        newColor[1] = (cl[1] * (splitXBy - col) + cr[1] * col) / splitXBy | 0;\n        newColor[2] = (cl[2] * (splitXBy - col) + cr[2] * col) / splitXBy | 0;\n        colors.push(newColor);\n      }\n    }\n    figureCoords[0] = pi[0];\n    figureColors[0] = ci[0];\n    figureCoords[splitXBy] = pi[3];\n    figureColors[splitXBy] = ci[1];\n    figureCoords[verticesPerRow * splitYBy] = pi[12];\n    figureColors[verticesPerRow * splitYBy] = ci[2];\n    figureCoords[verticesPerRow * splitYBy + splitXBy] = pi[15];\n    figureColors[verticesPerRow * splitYBy + splitXBy] = ci[3];\n    this.figures[index] = {\n      type: \"lattice\",\n      coords: figureCoords,\n      colors: figureColors,\n      verticesPerRow\n    };\n  }\n  _updateBounds() {\n    let minX = this.coords[0][0],\n      minY = this.coords[0][1],\n      maxX = minX,\n      maxY = minY;\n    for (let i = 1, ii = this.coords.length; i < ii; i++) {\n      const x = this.coords[i][0],\n        y = this.coords[i][1];\n      minX = minX > x ? x : minX;\n      minY = minY > y ? y : minY;\n      maxX = maxX < x ? x : maxX;\n      maxY = maxY < y ? y : maxY;\n    }\n    this.bounds = [minX, minY, maxX, maxY];\n  }\n  _packData() {\n    let i, ii, j, jj;\n    const coords = this.coords;\n    const coordsPacked = new Float32Array(coords.length * 2);\n    for (i = 0, j = 0, ii = coords.length; i < ii; i++) {\n      const xy = coords[i];\n      coordsPacked[j++] = xy[0];\n      coordsPacked[j++] = xy[1];\n    }\n    this.coords = coordsPacked;\n    const colors = this.colors;\n    const colorsPacked = new Uint8Array(colors.length * 3);\n    for (i = 0, j = 0, ii = colors.length; i < ii; i++) {\n      const c = colors[i];\n      colorsPacked[j++] = c[0];\n      colorsPacked[j++] = c[1];\n      colorsPacked[j++] = c[2];\n    }\n    this.colors = colorsPacked;\n    const figures = this.figures;\n    for (i = 0, ii = figures.length; i < ii; i++) {\n      const figure = figures[i],\n        ps = figure.coords,\n        cs = figure.colors;\n      for (j = 0, jj = ps.length; j < jj; j++) {\n        ps[j] *= 2;\n        cs[j] *= 3;\n      }\n    }\n  }\n  getIR() {\n    return [\"Mesh\", this.shadingType, this.coords, this.colors, this.figures, this.bounds, this.bbox, this.background];\n  }\n}\nclass DummyShading extends BaseShading {\n  getIR() {\n    return [\"Dummy\"];\n  }\n}\nfunction getTilingPatternIR(operatorList, dict, color) {\n  const matrix = dict.getArray(\"Matrix\");\n  const bbox = Util.normalizeRect(dict.getArray(\"BBox\"));\n  const xstep = dict.get(\"XStep\");\n  const ystep = dict.get(\"YStep\");\n  const paintType = dict.get(\"PaintType\");\n  const tilingType = dict.get(\"TilingType\");\n  if (bbox[2] - bbox[0] === 0 || bbox[3] - bbox[1] === 0) {\n    throw new FormatError(`Invalid getTilingPatternIR /BBox array: [${bbox}].`);\n  }\n  return [\"TilingPattern\", color, operatorList, matrix, bbox, xstep, ystep, paintType, tilingType];\n}\n\n;// ./src/core/calibri_factors.js\nconst CalibriBoldFactors = [1.3877, 1, 1, 1, 0.97801, 0.92482, 0.89552, 0.91133, 0.81988, 0.97566, 0.98152, 0.93548, 0.93548, 1.2798, 0.85284, 0.92794, 1, 0.96134, 1.54657, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.82845, 0.82845, 0.85284, 0.85284, 0.85284, 0.75859, 0.92138, 0.83908, 0.7762, 0.73293, 0.87289, 0.73133, 0.7514, 0.81921, 0.87356, 0.95958, 0.59526, 0.75727, 0.69225, 1.04924, 0.9121, 0.86943, 0.79795, 0.88198, 0.77958, 0.70864, 0.81055, 0.90399, 0.88653, 0.96017, 0.82577, 0.77892, 0.78257, 0.97507, 1.54657, 0.97507, 0.85284, 0.89552, 0.90176, 0.88762, 0.8785, 0.75241, 0.8785, 0.90518, 0.95015, 0.77618, 0.8785, 0.88401, 0.91916, 0.86304, 0.88401, 0.91488, 0.8785, 0.8801, 0.8785, 0.8785, 0.91343, 0.7173, 1.04106, 0.8785, 0.85075, 0.95794, 0.82616, 0.85162, 0.79492, 0.88331, 1.69808, 0.88331, 0.85284, 0.97801, 0.89552, 0.91133, 0.89552, 0.91133, 1.7801, 0.89552, 1.24487, 1.13254, 1.12401, 0.96839, 0.85284, 0.68787, 0.70645, 0.85592, 0.90747, 1.01466, 1.0088, 0.90323, 1, 1.07463, 1, 0.91056, 0.75806, 1.19118, 0.96839, 0.78864, 0.82845, 0.84133, 0.75859, 0.83908, 0.83908, 0.83908, 0.83908, 0.83908, 0.83908, 0.77539, 0.73293, 0.73133, 0.73133, 0.73133, 0.73133, 0.95958, 0.95958, 0.95958, 0.95958, 0.88506, 0.9121, 0.86943, 0.86943, 0.86943, 0.86943, 0.86943, 0.85284, 0.87508, 0.90399, 0.90399, 0.90399, 0.90399, 0.77892, 0.79795, 0.90807, 0.88762, 0.88762, 0.88762, 0.88762, 0.88762, 0.88762, 0.8715, 0.75241, 0.90518, 0.90518, 0.90518, 0.90518, 0.88401, 0.88401, 0.88401, 0.88401, 0.8785, 0.8785, 0.8801, 0.8801, 0.8801, 0.8801, 0.8801, 0.90747, 0.89049, 0.8785, 0.8785, 0.8785, 0.8785, 0.85162, 0.8785, 0.85162, 0.83908, 0.88762, 0.83908, 0.88762, 0.83908, 0.88762, 0.73293, 0.75241, 0.73293, 0.75241, 0.73293, 0.75241, 0.73293, 0.75241, 0.87289, 0.83016, 0.88506, 0.93125, 0.73133, 0.90518, 0.73133, 0.90518, 0.73133, 0.90518, 0.73133, 0.90518, 0.73133, 0.90518, 0.81921, 0.77618, 0.81921, 0.77618, 0.81921, 0.77618, 1, 1, 0.87356, 0.8785, 0.91075, 0.89608, 0.95958, 0.88401, 0.95958, 0.88401, 0.95958, 0.88401, 0.95958, 0.88401, 0.95958, 0.88401, 0.76229, 0.90167, 0.59526, 0.91916, 1, 1, 0.86304, 0.69225, 0.88401, 1, 1, 0.70424, 0.79468, 0.91926, 0.88175, 0.70823, 0.94903, 0.9121, 0.8785, 1, 1, 0.9121, 0.8785, 0.87802, 0.88656, 0.8785, 0.86943, 0.8801, 0.86943, 0.8801, 0.86943, 0.8801, 0.87402, 0.89291, 0.77958, 0.91343, 1, 1, 0.77958, 0.91343, 0.70864, 0.7173, 0.70864, 0.7173, 0.70864, 0.7173, 0.70864, 0.7173, 1, 1, 0.81055, 0.75841, 0.81055, 1.06452, 0.90399, 0.8785, 0.90399, 0.8785, 0.90399, 0.8785, 0.90399, 0.8785, 0.90399, 0.8785, 0.90399, 0.8785, 0.96017, 0.95794, 0.77892, 0.85162, 0.77892, 0.78257, 0.79492, 0.78257, 0.79492, 0.78257, 0.79492, 0.9297, 0.56892, 0.83908, 0.88762, 0.77539, 0.8715, 0.87508, 0.89049, 1, 1, 0.81055, 1.04106, 1.20528, 1.20528, 1, 1.15543, 0.70674, 0.98387, 0.94721, 1.33431, 1.45894, 0.95161, 1.06303, 0.83908, 0.80352, 0.57184, 0.6965, 0.56289, 0.82001, 0.56029, 0.81235, 1.02988, 0.83908, 0.7762, 0.68156, 0.80367, 0.73133, 0.78257, 0.87356, 0.86943, 0.95958, 0.75727, 0.89019, 1.04924, 0.9121, 0.7648, 0.86943, 0.87356, 0.79795, 0.78275, 0.81055, 0.77892, 0.9762, 0.82577, 0.99819, 0.84896, 0.95958, 0.77892, 0.96108, 1.01407, 0.89049, 1.02988, 0.94211, 0.96108, 0.8936, 0.84021, 0.87842, 0.96399, 0.79109, 0.89049, 1.00813, 1.02988, 0.86077, 0.87445, 0.92099, 0.84723, 0.86513, 0.8801, 0.75638, 0.85714, 0.78216, 0.79586, 0.87965, 0.94211, 0.97747, 0.78287, 0.97926, 0.84971, 1.02988, 0.94211, 0.8801, 0.94211, 0.84971, 0.73133, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90264, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90518, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90548, 1, 1, 1, 1, 1, 1, 0.96017, 0.95794, 0.96017, 0.95794, 0.96017, 0.95794, 0.77892, 0.85162, 1, 1, 0.89552, 0.90527, 1, 0.90363, 0.92794, 0.92794, 0.92794, 0.92794, 0.87012, 0.87012, 0.87012, 0.89552, 0.89552, 1.42259, 0.71143, 1.06152, 1, 1, 1.03372, 1.03372, 0.97171, 1.4956, 2.2807, 0.93835, 0.83406, 0.91133, 0.84107, 0.91133, 1, 1, 1, 0.72021, 1, 1.23108, 0.83489, 0.88525, 0.88525, 0.81499, 0.90527, 1.81055, 0.90527, 1.81055, 1.31006, 1.53711, 0.94434, 1.08696, 1, 0.95018, 0.77192, 0.85284, 0.90747, 1.17534, 0.69825, 0.9716, 1.37077, 0.90747, 0.90747, 0.85356, 0.90747, 0.90747, 1.44947, 0.85284, 0.8941, 0.8941, 0.70572, 0.8, 0.70572, 0.70572, 0.70572, 0.70572, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.99862, 0.99862, 1, 1, 1, 1, 1, 1.08004, 0.91027, 1, 1, 1, 0.99862, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90727, 0.90727, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];\nconst CalibriBoldMetrics = {\n  lineHeight: 1.2207,\n  lineGap: 0.2207\n};\nconst CalibriBoldItalicFactors = [1.3877, 1, 1, 1, 0.97801, 0.92482, 0.89552, 0.91133, 0.81988, 0.97566, 0.98152, 0.93548, 0.93548, 1.2798, 0.85284, 0.92794, 1, 0.96134, 1.56239, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.82845, 0.82845, 0.85284, 0.85284, 0.85284, 0.75859, 0.92138, 0.83908, 0.7762, 0.71805, 0.87289, 0.73133, 0.7514, 0.81921, 0.87356, 0.95958, 0.59526, 0.75727, 0.69225, 1.04924, 0.90872, 0.85938, 0.79795, 0.87068, 0.77958, 0.69766, 0.81055, 0.90399, 0.88653, 0.96068, 0.82577, 0.77892, 0.78257, 0.97507, 1.529, 0.97507, 0.85284, 0.89552, 0.90176, 0.94908, 0.86411, 0.74012, 0.86411, 0.88323, 0.95015, 0.86411, 0.86331, 0.88401, 0.91916, 0.86304, 0.88401, 0.9039, 0.86331, 0.86331, 0.86411, 0.86411, 0.90464, 0.70852, 1.04106, 0.86331, 0.84372, 0.95794, 0.82616, 0.84548, 0.79492, 0.88331, 1.69808, 0.88331, 0.85284, 0.97801, 0.89552, 0.91133, 0.89552, 0.91133, 1.7801, 0.89552, 1.24487, 1.13254, 1.19129, 0.96839, 0.85284, 0.68787, 0.70645, 0.85592, 0.90747, 1.01466, 1.0088, 0.90323, 1, 1.07463, 1, 0.91056, 0.75806, 1.19118, 0.96839, 0.78864, 0.82845, 0.84133, 0.75859, 0.83908, 0.83908, 0.83908, 0.83908, 0.83908, 0.83908, 0.77539, 0.71805, 0.73133, 0.73133, 0.73133, 0.73133, 0.95958, 0.95958, 0.95958, 0.95958, 0.88506, 0.90872, 0.85938, 0.85938, 0.85938, 0.85938, 0.85938, 0.85284, 0.87068, 0.90399, 0.90399, 0.90399, 0.90399, 0.77892, 0.79795, 0.90807, 0.94908, 0.94908, 0.94908, 0.94908, 0.94908, 0.94908, 0.85887, 0.74012, 0.88323, 0.88323, 0.88323, 0.88323, 0.88401, 0.88401, 0.88401, 0.88401, 0.8785, 0.86331, 0.86331, 0.86331, 0.86331, 0.86331, 0.86331, 0.90747, 0.89049, 0.86331, 0.86331, 0.86331, 0.86331, 0.84548, 0.86411, 0.84548, 0.83908, 0.94908, 0.83908, 0.94908, 0.83908, 0.94908, 0.71805, 0.74012, 0.71805, 0.74012, 0.71805, 0.74012, 0.71805, 0.74012, 0.87289, 0.79538, 0.88506, 0.92726, 0.73133, 0.88323, 0.73133, 0.88323, 0.73133, 0.88323, 0.73133, 0.88323, 0.73133, 0.88323, 0.81921, 0.86411, 0.81921, 0.86411, 0.81921, 0.86411, 1, 1, 0.87356, 0.86331, 0.91075, 0.8777, 0.95958, 0.88401, 0.95958, 0.88401, 0.95958, 0.88401, 0.95958, 0.88401, 0.95958, 0.88401, 0.76467, 0.90167, 0.59526, 0.91916, 1, 1, 0.86304, 0.69225, 0.88401, 1, 1, 0.70424, 0.77312, 0.91926, 0.88175, 0.70823, 0.94903, 0.90872, 0.86331, 1, 1, 0.90872, 0.86331, 0.86906, 0.88116, 0.86331, 0.85938, 0.86331, 0.85938, 0.86331, 0.85938, 0.86331, 0.87402, 0.86549, 0.77958, 0.90464, 1, 1, 0.77958, 0.90464, 0.69766, 0.70852, 0.69766, 0.70852, 0.69766, 0.70852, 0.69766, 0.70852, 1, 1, 0.81055, 0.75841, 0.81055, 1.06452, 0.90399, 0.86331, 0.90399, 0.86331, 0.90399, 0.86331, 0.90399, 0.86331, 0.90399, 0.86331, 0.90399, 0.86331, 0.96068, 0.95794, 0.77892, 0.84548, 0.77892, 0.78257, 0.79492, 0.78257, 0.79492, 0.78257, 0.79492, 0.9297, 0.56892, 0.83908, 0.94908, 0.77539, 0.85887, 0.87068, 0.89049, 1, 1, 0.81055, 1.04106, 1.20528, 1.20528, 1, 1.15543, 0.70088, 0.98387, 0.94721, 1.33431, 1.45894, 0.95161, 1.48387, 0.83908, 0.80352, 0.57118, 0.6965, 0.56347, 0.79179, 0.55853, 0.80346, 1.02988, 0.83908, 0.7762, 0.67174, 0.86036, 0.73133, 0.78257, 0.87356, 0.86441, 0.95958, 0.75727, 0.89019, 1.04924, 0.90872, 0.74889, 0.85938, 0.87891, 0.79795, 0.7957, 0.81055, 0.77892, 0.97447, 0.82577, 0.97466, 0.87179, 0.95958, 0.77892, 0.94252, 0.95612, 0.8753, 1.02988, 0.92733, 0.94252, 0.87411, 0.84021, 0.8728, 0.95612, 0.74081, 0.8753, 1.02189, 1.02988, 0.84814, 0.87445, 0.91822, 0.84723, 0.85668, 0.86331, 0.81344, 0.87581, 0.76422, 0.82046, 0.96057, 0.92733, 0.99375, 0.78022, 0.95452, 0.86015, 1.02988, 0.92733, 0.86331, 0.92733, 0.86015, 0.73133, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90631, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.88323, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.85174, 1, 1, 1, 1, 1, 1, 0.96068, 0.95794, 0.96068, 0.95794, 0.96068, 0.95794, 0.77892, 0.84548, 1, 1, 0.89552, 0.90527, 1, 0.90363, 0.92794, 0.92794, 0.92794, 0.89807, 0.87012, 0.87012, 0.87012, 0.89552, 0.89552, 1.42259, 0.71094, 1.06152, 1, 1, 1.03372, 1.03372, 0.97171, 1.4956, 2.2807, 0.92972, 0.83406, 0.91133, 0.83326, 0.91133, 1, 1, 1, 0.72021, 1, 1.23108, 0.83489, 0.88525, 0.88525, 0.81499, 0.90616, 1.81055, 0.90527, 1.81055, 1.3107, 1.53711, 0.94434, 1.08696, 1, 0.95018, 0.77192, 0.85284, 0.90747, 1.17534, 0.69825, 0.9716, 1.37077, 0.90747, 0.90747, 0.85356, 0.90747, 0.90747, 1.44947, 0.85284, 0.8941, 0.8941, 0.70572, 0.8, 0.70572, 0.70572, 0.70572, 0.70572, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.99862, 0.99862, 1, 1, 1, 1, 1, 1.08004, 0.91027, 1, 1, 1, 0.99862, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90727, 0.90727, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];\nconst CalibriBoldItalicMetrics = {\n  lineHeight: 1.2207,\n  lineGap: 0.2207\n};\nconst CalibriItalicFactors = [1.3877, 1, 1, 1, 1.17223, 1.1293, 0.89552, 0.91133, 0.80395, 1.02269, 1.15601, 0.91056, 0.91056, 1.2798, 0.85284, 0.89807, 1, 0.90861, 1.39543, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.96309, 0.96309, 0.85284, 0.85284, 0.85284, 0.83319, 0.88071, 0.8675, 0.81552, 0.72346, 0.85193, 0.73206, 0.7522, 0.81105, 0.86275, 0.90685, 0.6377, 0.77892, 0.75593, 1.02638, 0.89249, 0.84118, 0.77452, 0.85374, 0.75186, 0.67789, 0.79776, 0.88844, 0.85066, 0.94309, 0.77818, 0.7306, 0.76659, 1.10369, 1.38313, 1.10369, 1.06139, 0.89552, 0.8739, 0.9245, 0.9245, 0.83203, 0.9245, 0.85865, 1.09842, 0.9245, 0.9245, 1.03297, 1.07692, 0.90918, 1.03297, 0.94959, 0.9245, 0.92274, 0.9245, 0.9245, 1.02933, 0.77832, 1.20562, 0.9245, 0.8916, 0.98986, 0.86621, 0.89453, 0.79004, 0.94152, 1.77256, 0.94152, 0.85284, 0.97801, 0.89552, 0.91133, 0.89552, 0.91133, 1.91729, 0.89552, 1.17889, 1.13254, 1.16359, 0.92098, 0.85284, 0.68787, 0.71353, 0.84737, 0.90747, 1.0088, 1.0044, 0.87683, 1, 1.09091, 1, 0.92229, 0.739, 1.15642, 0.92098, 0.76288, 0.80504, 0.80972, 0.75859, 0.8675, 0.8675, 0.8675, 0.8675, 0.8675, 0.8675, 0.76318, 0.72346, 0.73206, 0.73206, 0.73206, 0.73206, 0.90685, 0.90685, 0.90685, 0.90685, 0.86477, 0.89249, 0.84118, 0.84118, 0.84118, 0.84118, 0.84118, 0.85284, 0.84557, 0.88844, 0.88844, 0.88844, 0.88844, 0.7306, 0.77452, 0.86331, 0.9245, 0.9245, 0.9245, 0.9245, 0.9245, 0.9245, 0.84843, 0.83203, 0.85865, 0.85865, 0.85865, 0.85865, 0.82601, 0.82601, 0.82601, 0.82601, 0.94469, 0.9245, 0.92274, 0.92274, 0.92274, 0.92274, 0.92274, 0.90747, 0.86651, 0.9245, 0.9245, 0.9245, 0.9245, 0.89453, 0.9245, 0.89453, 0.8675, 0.9245, 0.8675, 0.9245, 0.8675, 0.9245, 0.72346, 0.83203, 0.72346, 0.83203, 0.72346, 0.83203, 0.72346, 0.83203, 0.85193, 0.8875, 0.86477, 0.99034, 0.73206, 0.85865, 0.73206, 0.85865, 0.73206, 0.85865, 0.73206, 0.85865, 0.73206, 0.85865, 0.81105, 0.9245, 0.81105, 0.9245, 0.81105, 0.9245, 1, 1, 0.86275, 0.9245, 0.90872, 0.93591, 0.90685, 0.82601, 0.90685, 0.82601, 0.90685, 0.82601, 0.90685, 1.03297, 0.90685, 0.82601, 0.77896, 1.05611, 0.6377, 1.07692, 1, 1, 0.90918, 0.75593, 1.03297, 1, 1, 0.76032, 0.9375, 0.98156, 0.93407, 0.77261, 1.11429, 0.89249, 0.9245, 1, 1, 0.89249, 0.9245, 0.92534, 0.86698, 0.9245, 0.84118, 0.92274, 0.84118, 0.92274, 0.84118, 0.92274, 0.8667, 0.86291, 0.75186, 1.02933, 1, 1, 0.75186, 1.02933, 0.67789, 0.77832, 0.67789, 0.77832, 0.67789, 0.77832, 0.67789, 0.77832, 1, 1, 0.79776, 0.97655, 0.79776, 1.23023, 0.88844, 0.9245, 0.88844, 0.9245, 0.88844, 0.9245, 0.88844, 0.9245, 0.88844, 0.9245, 0.88844, 0.9245, 0.94309, 0.98986, 0.7306, 0.89453, 0.7306, 0.76659, 0.79004, 0.76659, 0.79004, 0.76659, 0.79004, 1.09231, 0.54873, 0.8675, 0.9245, 0.76318, 0.84843, 0.84557, 0.86651, 1, 1, 0.79776, 1.20562, 1.18622, 1.18622, 1, 1.1437, 0.67009, 0.96334, 0.93695, 1.35191, 1.40909, 0.95161, 1.48387, 0.8675, 0.90861, 0.6192, 0.7363, 0.64824, 0.82411, 0.56321, 0.85696, 1.23516, 0.8675, 0.81552, 0.7286, 0.84134, 0.73206, 0.76659, 0.86275, 0.84369, 0.90685, 0.77892, 0.85871, 1.02638, 0.89249, 0.75828, 0.84118, 0.85984, 0.77452, 0.76466, 0.79776, 0.7306, 0.90782, 0.77818, 0.903, 0.87291, 0.90685, 0.7306, 0.99058, 1.03667, 0.94635, 1.23516, 0.9849, 0.99058, 0.92393, 0.8916, 0.942, 1.03667, 0.75026, 0.94635, 1.0297, 1.23516, 0.90918, 0.94048, 0.98217, 0.89746, 0.84153, 0.92274, 0.82507, 0.88832, 0.84438, 0.88178, 1.03525, 0.9849, 1.00225, 0.78086, 0.97248, 0.89404, 1.23516, 0.9849, 0.92274, 0.9849, 0.89404, 0.73206, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.89693, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.85865, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90933, 1, 1, 1, 1, 1, 1, 0.94309, 0.98986, 0.94309, 0.98986, 0.94309, 0.98986, 0.7306, 0.89453, 1, 1, 0.89552, 0.90527, 1, 0.90186, 1.12308, 1.12308, 1.12308, 1.12308, 1.2566, 1.2566, 1.2566, 0.89552, 0.89552, 1.42259, 0.68994, 1.03809, 1, 1, 1.0176, 1.0176, 1.11523, 1.4956, 2.01462, 0.97858, 0.82616, 0.91133, 0.83437, 0.91133, 1, 1, 1, 0.70508, 1, 1.23108, 0.79801, 0.84426, 0.84426, 0.774, 0.90572, 1.81055, 0.90749, 1.81055, 1.28809, 1.55469, 0.94434, 1.07806, 1, 0.97094, 0.7589, 0.85284, 0.90747, 1.19658, 0.69825, 0.97622, 1.33512, 0.90747, 0.90747, 0.85284, 0.90747, 0.90747, 1.44947, 0.85284, 0.8941, 0.8941, 0.70572, 0.8, 0.70572, 0.70572, 0.70572, 0.70572, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.99862, 0.99862, 1, 1, 1, 1, 1, 1.0336, 0.91027, 1, 1, 1, 0.99862, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.05859, 1.05859, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];\nconst CalibriItalicMetrics = {\n  lineHeight: 1.2207,\n  lineGap: 0.2207\n};\nconst CalibriRegularFactors = [1.3877, 1, 1, 1, 1.17223, 1.1293, 0.89552, 0.91133, 0.80395, 1.02269, 1.15601, 0.91056, 0.91056, 1.2798, 0.85284, 0.89807, 1, 0.90861, 1.39016, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.96309, 0.96309, 0.85284, 0.85284, 0.85284, 0.83319, 0.88071, 0.8675, 0.81552, 0.73834, 0.85193, 0.73206, 0.7522, 0.81105, 0.86275, 0.90685, 0.6377, 0.77892, 0.75593, 1.02638, 0.89385, 0.85122, 0.77452, 0.86503, 0.75186, 0.68887, 0.79776, 0.88844, 0.85066, 0.94258, 0.77818, 0.7306, 0.76659, 1.10369, 1.39016, 1.10369, 1.06139, 0.89552, 0.8739, 0.86128, 0.94469, 0.8457, 0.94469, 0.89464, 1.09842, 0.84636, 0.94469, 1.03297, 1.07692, 0.90918, 1.03297, 0.95897, 0.94469, 0.9482, 0.94469, 0.94469, 1.04692, 0.78223, 1.20562, 0.94469, 0.90332, 0.98986, 0.86621, 0.90527, 0.79004, 0.94152, 1.77256, 0.94152, 0.85284, 0.97801, 0.89552, 0.91133, 0.89552, 0.91133, 1.91729, 0.89552, 1.17889, 1.13254, 1.08707, 0.92098, 0.85284, 0.68787, 0.71353, 0.84737, 0.90747, 1.0088, 1.0044, 0.87683, 1, 1.09091, 1, 0.92229, 0.739, 1.15642, 0.92098, 0.76288, 0.80504, 0.80972, 0.75859, 0.8675, 0.8675, 0.8675, 0.8675, 0.8675, 0.8675, 0.76318, 0.73834, 0.73206, 0.73206, 0.73206, 0.73206, 0.90685, 0.90685, 0.90685, 0.90685, 0.86477, 0.89385, 0.85122, 0.85122, 0.85122, 0.85122, 0.85122, 0.85284, 0.85311, 0.88844, 0.88844, 0.88844, 0.88844, 0.7306, 0.77452, 0.86331, 0.86128, 0.86128, 0.86128, 0.86128, 0.86128, 0.86128, 0.8693, 0.8457, 0.89464, 0.89464, 0.89464, 0.89464, 0.82601, 0.82601, 0.82601, 0.82601, 0.94469, 0.94469, 0.9482, 0.9482, 0.9482, 0.9482, 0.9482, 0.90747, 0.86651, 0.94469, 0.94469, 0.94469, 0.94469, 0.90527, 0.94469, 0.90527, 0.8675, 0.86128, 0.8675, 0.86128, 0.8675, 0.86128, 0.73834, 0.8457, 0.73834, 0.8457, 0.73834, 0.8457, 0.73834, 0.8457, 0.85193, 0.92454, 0.86477, 0.9921, 0.73206, 0.89464, 0.73206, 0.89464, 0.73206, 0.89464, 0.73206, 0.89464, 0.73206, 0.89464, 0.81105, 0.84636, 0.81105, 0.84636, 0.81105, 0.84636, 1, 1, 0.86275, 0.94469, 0.90872, 0.95786, 0.90685, 0.82601, 0.90685, 0.82601, 0.90685, 0.82601, 0.90685, 1.03297, 0.90685, 0.82601, 0.77741, 1.05611, 0.6377, 1.07692, 1, 1, 0.90918, 0.75593, 1.03297, 1, 1, 0.76032, 0.90452, 0.98156, 1.11842, 0.77261, 1.11429, 0.89385, 0.94469, 1, 1, 0.89385, 0.94469, 0.95877, 0.86901, 0.94469, 0.85122, 0.9482, 0.85122, 0.9482, 0.85122, 0.9482, 0.8667, 0.90016, 0.75186, 1.04692, 1, 1, 0.75186, 1.04692, 0.68887, 0.78223, 0.68887, 0.78223, 0.68887, 0.78223, 0.68887, 0.78223, 1, 1, 0.79776, 0.92188, 0.79776, 1.23023, 0.88844, 0.94469, 0.88844, 0.94469, 0.88844, 0.94469, 0.88844, 0.94469, 0.88844, 0.94469, 0.88844, 0.94469, 0.94258, 0.98986, 0.7306, 0.90527, 0.7306, 0.76659, 0.79004, 0.76659, 0.79004, 0.76659, 0.79004, 1.09231, 0.54873, 0.8675, 0.86128, 0.76318, 0.8693, 0.85311, 0.86651, 1, 1, 0.79776, 1.20562, 1.18622, 1.18622, 1, 1.1437, 0.67742, 0.96334, 0.93695, 1.35191, 1.40909, 0.95161, 1.48387, 0.86686, 0.90861, 0.62267, 0.74359, 0.65649, 0.85498, 0.56963, 0.88254, 1.23516, 0.8675, 0.81552, 0.75443, 0.84503, 0.73206, 0.76659, 0.86275, 0.85122, 0.90685, 0.77892, 0.85746, 1.02638, 0.89385, 0.75657, 0.85122, 0.86275, 0.77452, 0.74171, 0.79776, 0.7306, 0.95165, 0.77818, 0.89772, 0.88831, 0.90685, 0.7306, 0.98142, 1.02191, 0.96576, 1.23516, 0.99018, 0.98142, 0.9236, 0.89258, 0.94035, 1.02191, 0.78848, 0.96576, 0.9561, 1.23516, 0.90918, 0.92578, 0.95424, 0.89746, 0.83969, 0.9482, 0.80113, 0.89442, 0.85208, 0.86155, 0.98022, 0.99018, 1.00452, 0.81209, 0.99247, 0.89181, 1.23516, 0.99018, 0.9482, 0.99018, 0.89181, 0.73206, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.88844, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.89464, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.96766, 1, 1, 1, 1, 1, 1, 0.94258, 0.98986, 0.94258, 0.98986, 0.94258, 0.98986, 0.7306, 0.90527, 1, 1, 0.89552, 0.90527, 1, 0.90186, 1.12308, 1.12308, 1.12308, 1.12308, 1.2566, 1.2566, 1.2566, 0.89552, 0.89552, 1.42259, 0.69043, 1.03809, 1, 1, 1.0176, 1.0176, 1.11523, 1.4956, 2.01462, 0.99331, 0.82616, 0.91133, 0.84286, 0.91133, 1, 1, 1, 0.70508, 1, 1.23108, 0.79801, 0.84426, 0.84426, 0.774, 0.90527, 1.81055, 0.90527, 1.81055, 1.28809, 1.55469, 0.94434, 1.07806, 1, 0.97094, 0.7589, 0.85284, 0.90747, 1.19658, 0.69825, 0.97622, 1.33512, 0.90747, 0.90747, 0.85356, 0.90747, 0.90747, 1.44947, 0.85284, 0.8941, 0.8941, 0.70572, 0.8, 0.70572, 0.70572, 0.70572, 0.70572, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.99862, 0.99862, 1, 1, 1, 1, 1, 1.0336, 0.91027, 1, 1, 1, 0.99862, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.05859, 1.05859, 1, 1, 1, 1.07185, 0.99413, 0.96334, 1.08065, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];\nconst CalibriRegularMetrics = {\n  lineHeight: 1.2207,\n  lineGap: 0.2207\n};\n\n;// ./src/core/helvetica_factors.js\nconst HelveticaBoldFactors = [0.76116, 1, 1, 1.0006, 0.99998, 0.99974, 0.99973, 0.99973, 0.99982, 0.99977, 1.00087, 0.99998, 0.99998, 0.99959, 1.00003, 1.0006, 0.99998, 1.0006, 1.0006, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99998, 1, 1.00003, 1.00003, 1.00003, 1.00026, 0.9999, 0.99977, 0.99977, 0.99977, 0.99977, 1.00001, 1.00026, 1.00022, 0.99977, 1.0006, 0.99973, 0.99977, 1.00026, 0.99999, 0.99977, 1.00022, 1.00001, 1.00022, 0.99977, 1.00001, 1.00026, 0.99977, 1.00001, 1.00016, 1.00001, 1.00001, 1.00026, 0.99998, 1.0006, 0.99998, 1.00003, 0.99973, 0.99998, 0.99973, 1.00026, 0.99973, 1.00026, 0.99973, 0.99998, 1.00026, 1.00026, 1.0006, 1.0006, 0.99973, 1.0006, 0.99982, 1.00026, 1.00026, 1.00026, 1.00026, 0.99959, 0.99973, 0.99998, 1.00026, 0.99973, 1.00022, 0.99973, 0.99973, 1, 0.99959, 1.00077, 0.99959, 1.00003, 0.99998, 0.99973, 0.99973, 0.99973, 0.99973, 1.00077, 0.99973, 0.99998, 1.00025, 0.99968, 0.99973, 1.00003, 1.00025, 0.60299, 1.00024, 1.06409, 1, 1, 0.99998, 1, 0.99973, 1.0006, 0.99998, 1, 0.99936, 0.99973, 1.00002, 1.00002, 1.00002, 1.00026, 0.99977, 0.99977, 0.99977, 0.99977, 0.99977, 0.99977, 1, 0.99977, 1.00001, 1.00001, 1.00001, 1.00001, 1.0006, 1.0006, 1.0006, 1.0006, 0.99977, 0.99977, 1.00022, 1.00022, 1.00022, 1.00022, 1.00022, 1.00003, 1.00022, 0.99977, 0.99977, 0.99977, 0.99977, 1.00001, 1.00001, 1.00026, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99982, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1.0006, 1.0006, 1.0006, 1.0006, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 1.06409, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 0.99973, 1.00026, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 1.03374, 0.99977, 1.00026, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00022, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.00042, 0.99973, 0.99973, 1.0006, 0.99977, 0.99973, 0.99973, 1.00026, 1.0006, 1.00026, 1.0006, 1.00026, 1.03828, 1.00026, 0.99999, 1.00026, 1.0006, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.9993, 0.9998, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 1, 1.00016, 0.99977, 0.99959, 0.99977, 0.99959, 0.99977, 0.99959, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00026, 0.99998, 1.00026, 0.8121, 1.00026, 0.99998, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 1.00016, 1.00022, 1.00001, 0.99973, 1.00001, 1.00026, 1, 1.00026, 1, 1.00026, 1, 1.0006, 0.99973, 0.99977, 0.99973, 1, 0.99982, 1.00022, 1.00026, 1.00001, 0.99973, 1.00026, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 1.00034, 0.99977, 1, 0.99997, 1.00026, 1.00078, 1.00036, 0.99973, 1.00013, 1.0006, 0.99977, 0.99977, 0.99988, 0.85148, 1.00001, 1.00026, 0.99977, 1.00022, 1.0006, 0.99977, 1.00001, 0.99999, 0.99977, 1.00069, 1.00022, 0.99977, 1.00001, 0.99984, 1.00026, 1.00001, 1.00024, 1.00001, 0.9999, 1, 1.0006, 1.00001, 1.00041, 0.99962, 1.00026, 1.0006, 0.99995, 1.00041, 0.99942, 0.99973, 0.99927, 1.00082, 0.99902, 1.00026, 1.00087, 1.0006, 1.00069, 0.99973, 0.99867, 0.99973, 0.9993, 1.00026, 1.00049, 1.00056, 1, 0.99988, 0.99935, 0.99995, 0.99954, 1.00055, 0.99945, 1.00032, 1.0006, 0.99995, 1.00026, 0.99995, 1.00032, 1.00001, 1.00008, 0.99971, 1.00019, 0.9994, 1.00001, 1.0006, 1.00044, 0.99973, 1.00023, 1.00047, 1, 0.99942, 0.99561, 0.99989, 1.00035, 0.99977, 1.00035, 0.99977, 1.00019, 0.99944, 1.00001, 1.00021, 0.99926, 1.00035, 1.00035, 0.99942, 1.00048, 0.99999, 0.99977, 1.00022, 1.00035, 1.00001, 0.99977, 1.00026, 0.99989, 1.00057, 1.00001, 0.99936, 1.00052, 1.00012, 0.99996, 1.00043, 1, 1.00035, 0.9994, 0.99976, 1.00035, 0.99973, 1.00052, 1.00041, 1.00119, 1.00037, 0.99973, 1.00002, 0.99986, 1.00041, 1.00041, 0.99902, 0.9996, 1.00034, 0.99999, 1.00026, 0.99999, 1.00026, 0.99973, 1.00052, 0.99973, 1, 0.99973, 1.00041, 1.00075, 0.9994, 1.0003, 0.99999, 1, 1.00041, 0.99955, 1, 0.99915, 0.99973, 0.99973, 1.00026, 1.00119, 0.99955, 0.99973, 1.0006, 0.99911, 1.0006, 1.00026, 0.99972, 1.00026, 0.99902, 1.00041, 0.99973, 0.99999, 1, 1, 1.00038, 1.0005, 1.00016, 1.00022, 1.00016, 1.00022, 1.00016, 1.00022, 1.00001, 0.99973, 1, 1, 0.99973, 1, 1, 0.99955, 1.0006, 1.0006, 1.0006, 1.0006, 1, 1, 1, 0.99973, 0.99973, 0.99972, 1, 1, 1.00106, 0.99999, 0.99998, 0.99998, 0.99999, 0.99998, 1.66475, 1, 0.99973, 0.99973, 1.00023, 0.99973, 0.99971, 1.00047, 1.00023, 1, 0.99991, 0.99984, 1.00002, 1.00002, 1.00002, 1.00002, 1, 1, 1, 1, 1, 1, 1, 0.99972, 1, 1.20985, 1.39713, 1.00003, 1.00031, 1.00015, 1, 0.99561, 1.00027, 1.00031, 1.00031, 0.99915, 1.00031, 1.00031, 0.99999, 1.00003, 0.99999, 0.99999, 1.41144, 1.6, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.40579, 1.40579, 1.36625, 0.99999, 1, 0.99861, 0.99861, 1, 1.00026, 1.00026, 1.00026, 1.00026, 0.99972, 0.99999, 0.99999, 0.99999, 0.99999, 1.40483, 1, 0.99977, 1.00054, 1, 1, 0.99953, 0.99962, 1.00042, 0.9995, 1, 1, 1, 1, 1, 1, 1, 1, 0.99998, 0.99998, 0.99998, 0.99998, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];\nconst HelveticaBoldMetrics = {\n  lineHeight: 1.2,\n  lineGap: 0.2\n};\nconst HelveticaBoldItalicFactors = [0.76116, 1, 1, 1.0006, 0.99998, 0.99974, 0.99973, 0.99973, 0.99982, 0.99977, 1.00087, 0.99998, 0.99998, 0.99959, 1.00003, 1.0006, 0.99998, 1.0006, 1.0006, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99998, 1, 1.00003, 1.00003, 1.00003, 1.00026, 0.9999, 0.99977, 0.99977, 0.99977, 0.99977, 1.00001, 1.00026, 1.00022, 0.99977, 1.0006, 0.99973, 0.99977, 1.00026, 0.99999, 0.99977, 1.00022, 1.00001, 1.00022, 0.99977, 1.00001, 1.00026, 0.99977, 1.00001, 1.00016, 1.00001, 1.00001, 1.00026, 0.99998, 1.0006, 0.99998, 1.00003, 0.99973, 0.99998, 0.99973, 1.00026, 0.99973, 1.00026, 0.99973, 0.99998, 1.00026, 1.00026, 1.0006, 1.0006, 0.99973, 1.0006, 0.99982, 1.00026, 1.00026, 1.00026, 1.00026, 0.99959, 0.99973, 0.99998, 1.00026, 0.99973, 1.00022, 0.99973, 0.99973, 1, 0.99959, 1.00077, 0.99959, 1.00003, 0.99998, 0.99973, 0.99973, 0.99973, 0.99973, 1.00077, 0.99973, 0.99998, 1.00025, 0.99968, 0.99973, 1.00003, 1.00025, 0.60299, 1.00024, 1.06409, 1, 1, 0.99998, 1, 0.99973, 1.0006, 0.99998, 1, 0.99936, 0.99973, 1.00002, 1.00002, 1.00002, 1.00026, 0.99977, 0.99977, 0.99977, 0.99977, 0.99977, 0.99977, 1, 0.99977, 1.00001, 1.00001, 1.00001, 1.00001, 1.0006, 1.0006, 1.0006, 1.0006, 0.99977, 0.99977, 1.00022, 1.00022, 1.00022, 1.00022, 1.00022, 1.00003, 1.00022, 0.99977, 0.99977, 0.99977, 0.99977, 1.00001, 1.00001, 1.00026, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99982, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1.0006, 1.0006, 1.0006, 1.0006, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 1.06409, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 0.99973, 1.00026, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 1.0044, 0.99977, 1.00026, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00022, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 0.99971, 0.99973, 0.99973, 1.0006, 0.99977, 0.99973, 0.99973, 1.00026, 1.0006, 1.00026, 1.0006, 1.00026, 1.01011, 1.00026, 0.99999, 1.00026, 1.0006, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.9993, 0.9998, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 1, 1.00016, 0.99977, 0.99959, 0.99977, 0.99959, 0.99977, 0.99959, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00026, 0.99998, 1.00026, 0.8121, 1.00026, 0.99998, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 1.00016, 1.00022, 1.00001, 0.99973, 1.00001, 1.00026, 1, 1.00026, 1, 1.00026, 1, 1.0006, 0.99973, 0.99977, 0.99973, 1, 0.99982, 1.00022, 1.00026, 1.00001, 0.99973, 1.00026, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99977, 1, 1, 1.00026, 0.99969, 0.99972, 0.99981, 0.9998, 1.0006, 0.99977, 0.99977, 1.00022, 0.91155, 1.00001, 1.00026, 0.99977, 1.00022, 1.0006, 0.99977, 1.00001, 0.99999, 0.99977, 0.99966, 1.00022, 1.00032, 1.00001, 0.99944, 1.00026, 1.00001, 0.99968, 1.00001, 1.00047, 1, 1.0006, 1.00001, 0.99981, 1.00101, 1.00026, 1.0006, 0.99948, 0.99981, 1.00064, 0.99973, 0.99942, 1.00101, 1.00061, 1.00026, 1.00069, 1.0006, 1.00014, 0.99973, 1.01322, 0.99973, 1.00065, 1.00026, 1.00012, 0.99923, 1, 1.00064, 1.00076, 0.99948, 1.00055, 1.00063, 1.00007, 0.99943, 1.0006, 0.99948, 1.00026, 0.99948, 0.99943, 1.00001, 1.00001, 1.00029, 1.00038, 1.00035, 1.00001, 1.0006, 1.0006, 0.99973, 0.99978, 1.00001, 1.00057, 0.99989, 0.99967, 0.99964, 0.99967, 0.99977, 0.99999, 0.99977, 1.00038, 0.99977, 1.00001, 0.99973, 1.00066, 0.99967, 0.99967, 1.00041, 0.99998, 0.99999, 0.99977, 1.00022, 0.99967, 1.00001, 0.99977, 1.00026, 0.99964, 1.00031, 1.00001, 0.99999, 0.99999, 1, 1.00023, 1, 1, 0.99999, 1.00035, 1.00001, 0.99999, 0.99973, 0.99977, 0.99999, 1.00058, 0.99973, 0.99973, 0.99955, 0.9995, 1.00026, 1.00026, 1.00032, 0.99989, 1.00034, 0.99999, 1.00026, 1.00026, 1.00026, 0.99973, 0.45998, 0.99973, 1.00026, 0.99973, 1.00001, 0.99999, 0.99982, 0.99994, 0.99996, 1, 1.00042, 1.00044, 1.00029, 1.00023, 0.99973, 0.99973, 1.00026, 0.99949, 1.00002, 0.99973, 1.0006, 1.0006, 1.0006, 0.99975, 1.00026, 1.00026, 1.00032, 0.98685, 0.99973, 1.00026, 1, 1, 0.99966, 1.00044, 1.00016, 1.00022, 1.00016, 1.00022, 1.00016, 1.00022, 1.00001, 0.99973, 1, 1, 0.99973, 1, 1, 0.99955, 1.0006, 1.0006, 1.0006, 1.0006, 1, 1, 1, 0.99973, 0.99973, 0.99972, 1, 1, 1.00106, 0.99999, 0.99998, 0.99998, 0.99999, 0.99998, 1.66475, 1, 0.99973, 0.99973, 1, 0.99973, 0.99971, 0.99978, 1, 1, 0.99991, 0.99984, 1.00002, 1.00002, 1.00002, 1.00002, 1.00098, 1, 1, 1, 1.00049, 1, 1, 0.99972, 1, 1.20985, 1.39713, 1.00003, 1.00031, 1.00015, 1, 0.99561, 1.00027, 1.00031, 1.00031, 0.99915, 1.00031, 1.00031, 0.99999, 1.00003, 0.99999, 0.99999, 1.41144, 1.6, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.40579, 1.40579, 1.36625, 0.99999, 1, 0.99861, 0.99861, 1, 1.00026, 1.00026, 1.00026, 1.00026, 0.99972, 0.99999, 0.99999, 0.99999, 0.99999, 1.40483, 1, 0.99977, 1.00054, 1, 1, 0.99953, 0.99962, 1.00042, 0.9995, 1, 1, 1, 1, 1, 1, 1, 1, 0.99998, 0.99998, 0.99998, 0.99998, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];\nconst HelveticaBoldItalicMetrics = {\n  lineHeight: 1.35,\n  lineGap: 0.2\n};\nconst HelveticaItalicFactors = [0.76116, 1, 1, 1.0006, 1.0006, 1.00006, 0.99973, 0.99973, 0.99982, 1.00001, 1.00043, 0.99998, 0.99998, 0.99959, 1.00003, 1.0006, 0.99998, 1.0006, 1.0006, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1.0006, 1, 1.00003, 1.00003, 1.00003, 0.99973, 0.99987, 1.00001, 1.00001, 0.99977, 0.99977, 1.00001, 1.00026, 1.00022, 0.99977, 1.0006, 1, 1.00001, 0.99973, 0.99999, 0.99977, 1.00022, 1.00001, 1.00022, 0.99977, 1.00001, 1.00026, 0.99977, 1.00001, 1.00016, 1.00001, 1.00001, 1.00026, 1.0006, 1.0006, 1.0006, 0.99949, 0.99973, 0.99998, 0.99973, 0.99973, 1, 0.99973, 0.99973, 1.0006, 0.99973, 0.99973, 0.99924, 0.99924, 1, 0.99924, 0.99999, 0.99973, 0.99973, 0.99973, 0.99973, 0.99998, 1, 1.0006, 0.99973, 1, 0.99977, 1, 1, 1, 1.00005, 1.0009, 1.00005, 1.00003, 0.99998, 0.99973, 0.99973, 0.99973, 0.99973, 1.0009, 0.99973, 0.99998, 1.00025, 0.99968, 0.99973, 1.00003, 1.00025, 0.60299, 1.00024, 1.06409, 1, 1, 0.99998, 1, 0.9998, 1.0006, 0.99998, 1, 0.99936, 0.99973, 1.00002, 1.00002, 1.00002, 1.00026, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1, 0.99977, 1.00001, 1.00001, 1.00001, 1.00001, 1.0006, 1.0006, 1.0006, 1.0006, 0.99977, 0.99977, 1.00022, 1.00022, 1.00022, 1.00022, 1.00022, 1.00003, 1.00022, 0.99977, 0.99977, 0.99977, 0.99977, 1.00001, 1.00001, 1.00026, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99982, 1, 0.99973, 0.99973, 0.99973, 0.99973, 1.0006, 1.0006, 1.0006, 1.0006, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1.06409, 1.00026, 0.99973, 0.99973, 0.99973, 0.99973, 1, 0.99973, 1, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 0.99977, 1, 0.99977, 1, 0.99977, 1, 0.99977, 1, 0.99977, 1.0288, 0.99977, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 0.99924, 1.0006, 1.0006, 0.99946, 1.00034, 1, 0.99924, 1.00001, 1, 1, 0.99973, 0.99924, 0.99973, 0.99924, 0.99973, 1.06311, 0.99973, 1.00024, 0.99973, 0.99924, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 1.00041, 0.9998, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1, 1.00016, 0.99977, 0.99998, 0.99977, 0.99998, 0.99977, 0.99998, 1.00001, 1, 1.00001, 1, 1.00001, 1, 1.00001, 1, 1.00026, 1.0006, 1.00026, 0.89547, 1.00026, 1.0006, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 1.00016, 0.99977, 1.00001, 1, 1.00001, 1.00026, 1, 1.00026, 1, 1.00026, 1, 0.99924, 0.99973, 1.00001, 0.99973, 1, 0.99982, 1.00022, 1.00026, 1.00001, 1, 1.00026, 1.0006, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 1.00001, 1, 1.00054, 0.99977, 1.00084, 1.00007, 0.99973, 1.00013, 0.99924, 1.00001, 1.00001, 0.99945, 0.91221, 1.00001, 1.00026, 0.99977, 1.00022, 1.0006, 1.00001, 1.00001, 0.99999, 0.99977, 0.99933, 1.00022, 1.00054, 1.00001, 1.00065, 1.00026, 1.00001, 1.0001, 1.00001, 1.00052, 1, 1.0006, 1.00001, 0.99945, 0.99897, 0.99968, 0.99924, 1.00036, 0.99945, 0.99949, 1, 1.0006, 0.99897, 0.99918, 0.99968, 0.99911, 0.99924, 1, 0.99962, 1.01487, 1, 1.0005, 0.99973, 1.00012, 1.00043, 1, 0.99995, 0.99994, 1.00036, 0.99947, 1.00019, 1.00063, 1.00025, 0.99924, 1.00036, 0.99973, 1.00036, 1.00025, 1.00001, 1.00001, 1.00027, 1.0001, 1.00068, 1.00001, 1.0006, 1.0006, 1, 1.00008, 0.99957, 0.99972, 0.9994, 0.99954, 0.99975, 1.00051, 1.00001, 1.00019, 1.00001, 1.0001, 0.99986, 1.00001, 1.00001, 1.00038, 0.99954, 0.99954, 0.9994, 1.00066, 0.99999, 0.99977, 1.00022, 1.00054, 1.00001, 0.99977, 1.00026, 0.99975, 1.0001, 1.00001, 0.99993, 0.9995, 0.99955, 1.00016, 0.99978, 0.99974, 1.00019, 1.00022, 0.99955, 1.00053, 0.99973, 1.00089, 1.00005, 0.99967, 1.00048, 0.99973, 1.00002, 1.00034, 0.99973, 0.99973, 0.99964, 1.00006, 1.00066, 0.99947, 0.99973, 0.98894, 0.99973, 1, 0.44898, 1, 0.99946, 1, 1.00039, 1.00082, 0.99991, 0.99991, 0.99985, 1.00022, 1.00023, 1.00061, 1.00006, 0.99966, 0.99973, 0.99973, 0.99973, 1.00019, 1.0008, 1, 0.99924, 0.99924, 0.99924, 0.99983, 1.00044, 0.99973, 0.99964, 0.98332, 1, 0.99973, 1, 1, 0.99962, 0.99895, 1.00016, 0.99977, 1.00016, 0.99977, 1.00016, 0.99977, 1.00001, 1, 1, 1, 0.99973, 1, 1, 0.99955, 0.99924, 0.99924, 0.99924, 0.99924, 0.99998, 0.99998, 0.99998, 0.99973, 0.99973, 0.99972, 1, 1, 1.00267, 0.99999, 0.99998, 0.99998, 1, 0.99998, 1.66475, 1, 0.99973, 0.99973, 1.00023, 0.99973, 1.00423, 0.99925, 0.99999, 1, 0.99991, 0.99984, 1.00002, 1.00002, 1.00002, 1.00002, 1.00049, 1, 1.00245, 1, 1, 1, 1, 0.96329, 1, 1.20985, 1.39713, 1.00003, 0.8254, 1.00015, 1, 1.00035, 1.00027, 1.00031, 1.00031, 1.00003, 1.00031, 1.00031, 0.99999, 1.00003, 0.99999, 0.99999, 1.41144, 1.6, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.40579, 1.40579, 1.36625, 0.99999, 1, 0.99861, 0.99861, 1, 1.00026, 1.00026, 1.00026, 1.00026, 0.95317, 0.99999, 0.99999, 0.99999, 0.99999, 1.40483, 1, 0.99977, 1.00054, 1, 1, 0.99953, 0.99962, 1.00042, 0.9995, 1, 1, 1, 1, 1, 1, 1, 1, 0.99998, 0.99998, 0.99998, 0.99998, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];\nconst HelveticaItalicMetrics = {\n  lineHeight: 1.35,\n  lineGap: 0.2\n};\nconst HelveticaRegularFactors = [0.76116, 1, 1, 1.0006, 1.0006, 1.00006, 0.99973, 0.99973, 0.99982, 1.00001, 1.00043, 0.99998, 0.99998, 0.99959, 1.00003, 1.0006, 0.99998, 1.0006, 1.0006, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1.0006, 1, 1.00003, 1.00003, 1.00003, 0.99973, 0.99987, 1.00001, 1.00001, 0.99977, 0.99977, 1.00001, 1.00026, 1.00022, 0.99977, 1.0006, 1, 1.00001, 0.99973, 0.99999, 0.99977, 1.00022, 1.00001, 1.00022, 0.99977, 1.00001, 1.00026, 0.99977, 1.00001, 1.00016, 1.00001, 1.00001, 1.00026, 1.0006, 1.0006, 1.0006, 0.99949, 0.99973, 0.99998, 0.99973, 0.99973, 1, 0.99973, 0.99973, 1.0006, 0.99973, 0.99973, 0.99924, 0.99924, 1, 0.99924, 0.99999, 0.99973, 0.99973, 0.99973, 0.99973, 0.99998, 1, 1.0006, 0.99973, 1, 0.99977, 1, 1, 1, 1.00005, 1.0009, 1.00005, 1.00003, 0.99998, 0.99973, 0.99973, 0.99973, 0.99973, 1.0009, 0.99973, 0.99998, 1.00025, 0.99968, 0.99973, 1.00003, 1.00025, 0.60299, 1.00024, 1.06409, 1, 1, 0.99998, 1, 0.9998, 1.0006, 0.99998, 1, 0.99936, 0.99973, 1.00002, 1.00002, 1.00002, 1.00026, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1, 0.99977, 1.00001, 1.00001, 1.00001, 1.00001, 1.0006, 1.0006, 1.0006, 1.0006, 0.99977, 0.99977, 1.00022, 1.00022, 1.00022, 1.00022, 1.00022, 1.00003, 1.00022, 0.99977, 0.99977, 0.99977, 0.99977, 1.00001, 1.00001, 1.00026, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99982, 1, 0.99973, 0.99973, 0.99973, 0.99973, 1.0006, 1.0006, 1.0006, 1.0006, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1.06409, 1.00026, 0.99973, 0.99973, 0.99973, 0.99973, 1, 0.99973, 1, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 0.99977, 1, 0.99977, 1, 0.99977, 1, 0.99977, 1, 0.99977, 1.04596, 0.99977, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 0.99924, 1.0006, 1.0006, 1.00019, 1.00034, 1, 0.99924, 1.00001, 1, 1, 0.99973, 0.99924, 0.99973, 0.99924, 0.99973, 1.02572, 0.99973, 1.00005, 0.99973, 0.99924, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99999, 0.9998, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1, 1.00016, 0.99977, 0.99998, 0.99977, 0.99998, 0.99977, 0.99998, 1.00001, 1, 1.00001, 1, 1.00001, 1, 1.00001, 1, 1.00026, 1.0006, 1.00026, 0.84533, 1.00026, 1.0006, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 1.00016, 0.99977, 1.00001, 1, 1.00001, 1.00026, 1, 1.00026, 1, 1.00026, 1, 0.99924, 0.99973, 1.00001, 0.99973, 1, 0.99982, 1.00022, 1.00026, 1.00001, 1, 1.00026, 1.0006, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99928, 1, 0.99977, 1.00013, 1.00055, 0.99947, 0.99945, 0.99941, 0.99924, 1.00001, 1.00001, 1.0004, 0.91621, 1.00001, 1.00026, 0.99977, 1.00022, 1.0006, 1.00001, 1.00005, 0.99999, 0.99977, 1.00015, 1.00022, 0.99977, 1.00001, 0.99973, 1.00026, 1.00001, 1.00019, 1.00001, 0.99946, 1, 1.0006, 1.00001, 0.99978, 1.00045, 0.99973, 0.99924, 1.00023, 0.99978, 0.99966, 1, 1.00065, 1.00045, 1.00019, 0.99973, 0.99973, 0.99924, 1, 1, 0.96499, 1, 1.00055, 0.99973, 1.00008, 1.00027, 1, 0.9997, 0.99995, 1.00023, 0.99933, 1.00019, 1.00015, 1.00031, 0.99924, 1.00023, 0.99973, 1.00023, 1.00031, 1.00001, 0.99928, 1.00029, 1.00092, 1.00035, 1.00001, 1.0006, 1.0006, 1, 0.99988, 0.99975, 1, 1.00082, 0.99561, 0.9996, 1.00035, 1.00001, 0.99962, 1.00001, 1.00092, 0.99964, 1.00001, 0.99963, 0.99999, 1.00035, 1.00035, 1.00082, 0.99962, 0.99999, 0.99977, 1.00022, 1.00035, 1.00001, 0.99977, 1.00026, 0.9996, 0.99967, 1.00001, 1.00034, 1.00074, 1.00054, 1.00053, 1.00063, 0.99971, 0.99962, 1.00035, 0.99975, 0.99977, 0.99973, 1.00043, 0.99953, 1.0007, 0.99915, 0.99973, 1.00008, 0.99892, 1.00073, 1.00073, 1.00114, 0.99915, 1.00073, 0.99955, 0.99973, 1.00092, 0.99973, 1, 0.99998, 1, 1.0003, 1, 1.00043, 1.00001, 0.99969, 1.0003, 1, 1.00035, 1.00001, 0.9995, 1, 1.00092, 0.99973, 0.99973, 0.99973, 1.0007, 0.9995, 1, 0.99924, 1.0006, 0.99924, 0.99972, 1.00062, 0.99973, 1.00114, 1.00073, 1, 0.99955, 1, 1, 1.00047, 0.99968, 1.00016, 0.99977, 1.00016, 0.99977, 1.00016, 0.99977, 1.00001, 1, 1, 1, 0.99973, 1, 1, 0.99955, 0.99924, 0.99924, 0.99924, 0.99924, 0.99998, 0.99998, 0.99998, 0.99973, 0.99973, 0.99972, 1, 1, 1.00267, 0.99999, 0.99998, 0.99998, 1, 0.99998, 1.66475, 1, 0.99973, 0.99973, 1.00023, 0.99973, 0.99971, 0.99925, 1.00023, 1, 0.99991, 0.99984, 1.00002, 1.00002, 1.00002, 1.00002, 1, 1, 1, 1, 1, 1, 1, 0.96329, 1, 1.20985, 1.39713, 1.00003, 0.8254, 1.00015, 1, 1.00035, 1.00027, 1.00031, 1.00031, 0.99915, 1.00031, 1.00031, 0.99999, 1.00003, 0.99999, 0.99999, 1.41144, 1.6, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.40579, 1.40579, 1.36625, 0.99999, 1, 0.99861, 0.99861, 1, 1.00026, 1.00026, 1.00026, 1.00026, 0.95317, 0.99999, 0.99999, 0.99999, 0.99999, 1.40483, 1, 0.99977, 1.00054, 1, 1, 0.99953, 0.99962, 1.00042, 0.9995, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];\nconst HelveticaRegularMetrics = {\n  lineHeight: 1.2,\n  lineGap: 0.2\n};\n\n;// ./src/core/liberationsans_widths.js\nconst LiberationSansBoldWidths = [365, 0, 333, 278, 333, 474, 556, 556, 889, 722, 238, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, 975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556, 333, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611, 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584, 333, 556, 556, 556, 556, 280, 556, 333, 737, 370, 556, 584, 737, 552, 400, 549, 333, 333, 333, 576, 556, 278, 333, 333, 365, 556, 834, 834, 834, 611, 722, 722, 722, 722, 722, 722, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 556, 556, 556, 556, 556, 278, 278, 278, 278, 611, 611, 611, 611, 611, 611, 611, 549, 611, 611, 611, 611, 611, 556, 611, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 719, 722, 611, 667, 556, 667, 556, 667, 556, 667, 556, 667, 556, 778, 611, 778, 611, 778, 611, 778, 611, 722, 611, 722, 611, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 785, 556, 556, 278, 722, 556, 556, 611, 278, 611, 278, 611, 385, 611, 479, 611, 278, 722, 611, 722, 611, 722, 611, 708, 723, 611, 778, 611, 778, 611, 778, 611, 1000, 944, 722, 389, 722, 389, 722, 389, 667, 556, 667, 556, 667, 556, 667, 556, 611, 333, 611, 479, 611, 333, 722, 611, 722, 611, 722, 611, 722, 611, 722, 611, 722, 611, 944, 778, 667, 556, 667, 611, 500, 611, 500, 611, 500, 278, 556, 722, 556, 1000, 889, 778, 611, 667, 556, 611, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 465, 722, 333, 853, 906, 474, 825, 927, 838, 278, 722, 722, 601, 719, 667, 611, 722, 778, 278, 722, 667, 833, 722, 644, 778, 722, 667, 600, 611, 667, 821, 667, 809, 802, 278, 667, 615, 451, 611, 278, 582, 615, 610, 556, 606, 475, 460, 611, 541, 278, 558, 556, 612, 556, 445, 611, 766, 619, 520, 684, 446, 582, 715, 576, 753, 845, 278, 582, 611, 582, 845, 667, 669, 885, 567, 711, 667, 278, 276, 556, 1094, 1062, 875, 610, 722, 622, 719, 722, 719, 722, 567, 712, 667, 904, 626, 719, 719, 610, 702, 833, 722, 778, 719, 667, 722, 611, 622, 854, 667, 730, 703, 1005, 1019, 870, 979, 719, 711, 1031, 719, 556, 618, 615, 417, 635, 556, 709, 497, 615, 615, 500, 635, 740, 604, 611, 604, 611, 556, 490, 556, 875, 556, 615, 581, 833, 844, 729, 854, 615, 552, 854, 583, 556, 556, 611, 417, 552, 556, 278, 281, 278, 969, 906, 611, 500, 615, 556, 604, 778, 611, 487, 447, 944, 778, 944, 778, 944, 778, 667, 556, 333, 333, 556, 1000, 1000, 552, 278, 278, 278, 278, 500, 500, 500, 556, 556, 350, 1000, 1000, 240, 479, 333, 333, 604, 333, 167, 396, 556, 556, 1094, 556, 885, 489, 1115, 1000, 768, 600, 834, 834, 834, 834, 1000, 500, 1000, 500, 1000, 500, 500, 494, 612, 823, 713, 584, 549, 713, 979, 722, 274, 549, 549, 583, 549, 549, 604, 584, 604, 604, 708, 625, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 729, 604, 604, 354, 354, 1000, 990, 990, 990, 990, 494, 604, 604, 604, 604, 354, 1021, 1052, 917, 750, 750, 531, 656, 594, 510, 500, 750, 750, 611, 611, 333, 333, 333, 333, 333, 333, 333, 333, 222, 222, 333, 333, 333, 333, 333, 333, 333, 333];\nconst LiberationSansBoldMapping = [-1, -1, -1, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 402, 506, 507, 508, 509, 510, 511, 536, 537, 538, 539, 710, 711, 713, 728, 729, 730, 731, 732, 733, 900, 901, 902, 903, 904, 905, 906, 908, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1138, 1139, 1168, 1169, 7808, 7809, 7810, 7811, 7812, 7813, 7922, 7923, 8208, 8209, 8211, 8212, 8213, 8215, 8216, 8217, 8218, 8219, 8220, 8221, 8222, 8224, 8225, 8226, 8230, 8240, 8242, 8243, 8249, 8250, 8252, 8254, 8260, 8319, 8355, 8356, 8359, 8364, 8453, 8467, 8470, 8482, 8486, 8494, 8539, 8540, 8541, 8542, 8592, 8593, 8594, 8595, 8596, 8597, 8616, 8706, 8710, 8719, 8721, 8722, 8730, 8734, 8735, 8745, 8747, 8776, 8800, 8801, 8804, 8805, 8962, 8976, 8992, 8993, 9472, 9474, 9484, 9488, 9492, 9496, 9500, 9508, 9516, 9524, 9532, 9552, 9553, 9554, 9555, 9556, 9557, 9558, 9559, 9560, 9561, 9562, 9563, 9564, 9565, 9566, 9567, 9568, 9569, 9570, 9571, 9572, 9573, 9574, 9575, 9576, 9577, 9578, 9579, 9580, 9600, 9604, 9608, 9612, 9616, 9617, 9618, 9619, 9632, 9633, 9642, 9643, 9644, 9650, 9658, 9660, 9668, 9674, 9675, 9679, 9688, 9689, 9702, 9786, 9787, 9788, 9792, 9794, 9824, 9827, 9829, 9830, 9834, 9835, 9836, 61441, 61442, 61445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1];\nconst LiberationSansBoldItalicWidths = [365, 0, 333, 278, 333, 474, 556, 556, 889, 722, 238, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, 975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556, 333, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611, 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584, 333, 556, 556, 556, 556, 280, 556, 333, 737, 370, 556, 584, 737, 552, 400, 549, 333, 333, 333, 576, 556, 278, 333, 333, 365, 556, 834, 834, 834, 611, 722, 722, 722, 722, 722, 722, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 556, 556, 556, 556, 556, 278, 278, 278, 278, 611, 611, 611, 611, 611, 611, 611, 549, 611, 611, 611, 611, 611, 556, 611, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 740, 722, 611, 667, 556, 667, 556, 667, 556, 667, 556, 667, 556, 778, 611, 778, 611, 778, 611, 778, 611, 722, 611, 722, 611, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 782, 556, 556, 278, 722, 556, 556, 611, 278, 611, 278, 611, 396, 611, 479, 611, 278, 722, 611, 722, 611, 722, 611, 708, 723, 611, 778, 611, 778, 611, 778, 611, 1000, 944, 722, 389, 722, 389, 722, 389, 667, 556, 667, 556, 667, 556, 667, 556, 611, 333, 611, 479, 611, 333, 722, 611, 722, 611, 722, 611, 722, 611, 722, 611, 722, 611, 944, 778, 667, 556, 667, 611, 500, 611, 500, 611, 500, 278, 556, 722, 556, 1000, 889, 778, 611, 667, 556, 611, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 722, 333, 854, 906, 473, 844, 930, 847, 278, 722, 722, 610, 671, 667, 611, 722, 778, 278, 722, 667, 833, 722, 657, 778, 718, 667, 590, 611, 667, 822, 667, 829, 781, 278, 667, 620, 479, 611, 278, 591, 620, 621, 556, 610, 479, 492, 611, 558, 278, 566, 556, 603, 556, 450, 611, 712, 605, 532, 664, 409, 591, 704, 578, 773, 834, 278, 591, 611, 591, 834, 667, 667, 886, 614, 719, 667, 278, 278, 556, 1094, 1042, 854, 622, 719, 677, 719, 722, 708, 722, 614, 722, 667, 927, 643, 719, 719, 615, 687, 833, 722, 778, 719, 667, 722, 611, 677, 781, 667, 729, 708, 979, 989, 854, 1000, 708, 719, 1042, 729, 556, 619, 604, 534, 618, 556, 736, 510, 611, 611, 507, 622, 740, 604, 611, 611, 611, 556, 889, 556, 885, 556, 646, 583, 889, 935, 707, 854, 594, 552, 865, 589, 556, 556, 611, 469, 563, 556, 278, 278, 278, 969, 906, 611, 507, 619, 556, 611, 778, 611, 575, 467, 944, 778, 944, 778, 944, 778, 667, 556, 333, 333, 556, 1000, 1000, 552, 278, 278, 278, 278, 500, 500, 500, 556, 556, 350, 1000, 1000, 240, 479, 333, 333, 604, 333, 167, 396, 556, 556, 1104, 556, 885, 516, 1146, 1000, 768, 600, 834, 834, 834, 834, 999, 500, 1000, 500, 1000, 500, 500, 494, 612, 823, 713, 584, 549, 713, 979, 722, 274, 549, 549, 583, 549, 549, 604, 584, 604, 604, 708, 625, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 729, 604, 604, 354, 354, 1000, 990, 990, 990, 990, 494, 604, 604, 604, 604, 354, 1021, 1052, 917, 750, 750, 531, 656, 594, 510, 500, 750, 750, 611, 611, 333, 333, 333, 333, 333, 333, 333, 333, 222, 222, 333, 333, 333, 333, 333, 333, 333, 333];\nconst LiberationSansBoldItalicMapping = [-1, -1, -1, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 402, 506, 507, 508, 509, 510, 511, 536, 537, 538, 539, 710, 711, 713, 728, 729, 730, 731, 732, 733, 900, 901, 902, 903, 904, 905, 906, 908, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1138, 1139, 1168, 1169, 7808, 7809, 7810, 7811, 7812, 7813, 7922, 7923, 8208, 8209, 8211, 8212, 8213, 8215, 8216, 8217, 8218, 8219, 8220, 8221, 8222, 8224, 8225, 8226, 8230, 8240, 8242, 8243, 8249, 8250, 8252, 8254, 8260, 8319, 8355, 8356, 8359, 8364, 8453, 8467, 8470, 8482, 8486, 8494, 8539, 8540, 8541, 8542, 8592, 8593, 8594, 8595, 8596, 8597, 8616, 8706, 8710, 8719, 8721, 8722, 8730, 8734, 8735, 8745, 8747, 8776, 8800, 8801, 8804, 8805, 8962, 8976, 8992, 8993, 9472, 9474, 9484, 9488, 9492, 9496, 9500, 9508, 9516, 9524, 9532, 9552, 9553, 9554, 9555, 9556, 9557, 9558, 9559, 9560, 9561, 9562, 9563, 9564, 9565, 9566, 9567, 9568, 9569, 9570, 9571, 9572, 9573, 9574, 9575, 9576, 9577, 9578, 9579, 9580, 9600, 9604, 9608, 9612, 9616, 9617, 9618, 9619, 9632, 9633, 9642, 9643, 9644, 9650, 9658, 9660, 9668, 9674, 9675, 9679, 9688, 9689, 9702, 9786, 9787, 9788, 9792, 9794, 9824, 9827, 9829, 9830, 9834, 9835, 9836, 61441, 61442, 61445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1];\nconst LiberationSansItalicWidths = [365, 0, 333, 278, 278, 355, 556, 556, 889, 667, 191, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, 333, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 333, 556, 556, 556, 556, 260, 556, 333, 737, 370, 556, 584, 737, 552, 400, 549, 333, 333, 333, 576, 537, 278, 333, 333, 365, 556, 834, 834, 834, 611, 667, 667, 667, 667, 667, 667, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 500, 556, 556, 556, 556, 278, 278, 278, 278, 556, 556, 556, 556, 556, 556, 556, 549, 611, 556, 556, 556, 556, 500, 556, 500, 667, 556, 667, 556, 667, 556, 722, 500, 722, 500, 722, 500, 722, 500, 722, 625, 722, 556, 667, 556, 667, 556, 667, 556, 667, 556, 667, 556, 778, 556, 778, 556, 778, 556, 778, 556, 722, 556, 722, 556, 278, 278, 278, 278, 278, 278, 278, 222, 278, 278, 733, 444, 500, 222, 667, 500, 500, 556, 222, 556, 222, 556, 281, 556, 400, 556, 222, 722, 556, 722, 556, 722, 556, 615, 723, 556, 778, 556, 778, 556, 778, 556, 1000, 944, 722, 333, 722, 333, 722, 333, 667, 500, 667, 500, 667, 500, 667, 500, 611, 278, 611, 354, 611, 278, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 944, 722, 667, 500, 667, 611, 500, 611, 500, 611, 500, 222, 556, 667, 556, 1000, 889, 778, 611, 667, 500, 611, 278, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 667, 278, 789, 846, 389, 794, 865, 775, 222, 667, 667, 570, 671, 667, 611, 722, 778, 278, 667, 667, 833, 722, 648, 778, 725, 667, 600, 611, 667, 837, 667, 831, 761, 278, 667, 570, 439, 555, 222, 550, 570, 571, 500, 556, 439, 463, 555, 542, 222, 500, 492, 548, 500, 447, 556, 670, 573, 486, 603, 374, 550, 652, 546, 728, 779, 222, 550, 556, 550, 779, 667, 667, 843, 544, 708, 667, 278, 278, 500, 1066, 982, 844, 589, 715, 639, 724, 667, 651, 667, 544, 704, 667, 917, 614, 715, 715, 589, 686, 833, 722, 778, 725, 667, 722, 611, 639, 795, 667, 727, 673, 920, 923, 805, 886, 651, 694, 1022, 682, 556, 562, 522, 493, 553, 556, 688, 465, 556, 556, 472, 564, 686, 550, 556, 556, 556, 500, 833, 500, 835, 500, 572, 518, 830, 851, 621, 736, 526, 492, 752, 534, 556, 556, 556, 378, 496, 500, 222, 222, 222, 910, 828, 556, 472, 565, 500, 556, 778, 556, 492, 339, 944, 722, 944, 722, 944, 722, 667, 500, 333, 333, 556, 1000, 1000, 552, 222, 222, 222, 222, 333, 333, 333, 556, 556, 350, 1000, 1000, 188, 354, 333, 333, 500, 333, 167, 365, 556, 556, 1094, 556, 885, 323, 1083, 1000, 768, 600, 834, 834, 834, 834, 1000, 500, 998, 500, 1000, 500, 500, 494, 612, 823, 713, 584, 549, 713, 979, 719, 274, 549, 549, 584, 549, 549, 604, 584, 604, 604, 708, 625, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 729, 604, 604, 354, 354, 1000, 990, 990, 990, 990, 494, 604, 604, 604, 604, 354, 1021, 1052, 917, 750, 750, 531, 656, 594, 510, 500, 750, 750, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 222, 222, 294, 294, 324, 324, 316, 328, 398, 285];\nconst LiberationSansItalicMapping = [-1, -1, -1, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 402, 506, 507, 508, 509, 510, 511, 536, 537, 538, 539, 710, 711, 713, 728, 729, 730, 731, 732, 733, 900, 901, 902, 903, 904, 905, 906, 908, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1138, 1139, 1168, 1169, 7808, 7809, 7810, 7811, 7812, 7813, 7922, 7923, 8208, 8209, 8211, 8212, 8213, 8215, 8216, 8217, 8218, 8219, 8220, 8221, 8222, 8224, 8225, 8226, 8230, 8240, 8242, 8243, 8249, 8250, 8252, 8254, 8260, 8319, 8355, 8356, 8359, 8364, 8453, 8467, 8470, 8482, 8486, 8494, 8539, 8540, 8541, 8542, 8592, 8593, 8594, 8595, 8596, 8597, 8616, 8706, 8710, 8719, 8721, 8722, 8730, 8734, 8735, 8745, 8747, 8776, 8800, 8801, 8804, 8805, 8962, 8976, 8992, 8993, 9472, 9474, 9484, 9488, 9492, 9496, 9500, 9508, 9516, 9524, 9532, 9552, 9553, 9554, 9555, 9556, 9557, 9558, 9559, 9560, 9561, 9562, 9563, 9564, 9565, 9566, 9567, 9568, 9569, 9570, 9571, 9572, 9573, 9574, 9575, 9576, 9577, 9578, 9579, 9580, 9600, 9604, 9608, 9612, 9616, 9617, 9618, 9619, 9632, 9633, 9642, 9643, 9644, 9650, 9658, 9660, 9668, 9674, 9675, 9679, 9688, 9689, 9702, 9786, 9787, 9788, 9792, 9794, 9824, 9827, 9829, 9830, 9834, 9835, 9836, 61441, 61442, 61445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1];\nconst LiberationSansRegularWidths = [365, 0, 333, 278, 278, 355, 556, 556, 889, 667, 191, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, 333, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 333, 556, 556, 556, 556, 260, 556, 333, 737, 370, 556, 584, 737, 552, 400, 549, 333, 333, 333, 576, 537, 278, 333, 333, 365, 556, 834, 834, 834, 611, 667, 667, 667, 667, 667, 667, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 500, 556, 556, 556, 556, 278, 278, 278, 278, 556, 556, 556, 556, 556, 556, 556, 549, 611, 556, 556, 556, 556, 500, 556, 500, 667, 556, 667, 556, 667, 556, 722, 500, 722, 500, 722, 500, 722, 500, 722, 615, 722, 556, 667, 556, 667, 556, 667, 556, 667, 556, 667, 556, 778, 556, 778, 556, 778, 556, 778, 556, 722, 556, 722, 556, 278, 278, 278, 278, 278, 278, 278, 222, 278, 278, 735, 444, 500, 222, 667, 500, 500, 556, 222, 556, 222, 556, 292, 556, 334, 556, 222, 722, 556, 722, 556, 722, 556, 604, 723, 556, 778, 556, 778, 556, 778, 556, 1000, 944, 722, 333, 722, 333, 722, 333, 667, 500, 667, 500, 667, 500, 667, 500, 611, 278, 611, 375, 611, 278, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 944, 722, 667, 500, 667, 611, 500, 611, 500, 611, 500, 222, 556, 667, 556, 1000, 889, 778, 611, 667, 500, 611, 278, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 667, 278, 784, 838, 384, 774, 855, 752, 222, 667, 667, 551, 668, 667, 611, 722, 778, 278, 667, 668, 833, 722, 650, 778, 722, 667, 618, 611, 667, 798, 667, 835, 748, 278, 667, 578, 446, 556, 222, 547, 578, 575, 500, 557, 446, 441, 556, 556, 222, 500, 500, 576, 500, 448, 556, 690, 569, 482, 617, 395, 547, 648, 525, 713, 781, 222, 547, 556, 547, 781, 667, 667, 865, 542, 719, 667, 278, 278, 500, 1057, 1010, 854, 583, 722, 635, 719, 667, 656, 667, 542, 677, 667, 923, 604, 719, 719, 583, 656, 833, 722, 778, 719, 667, 722, 611, 635, 760, 667, 740, 667, 917, 938, 792, 885, 656, 719, 1010, 722, 556, 573, 531, 365, 583, 556, 669, 458, 559, 559, 438, 583, 688, 552, 556, 542, 556, 500, 458, 500, 823, 500, 573, 521, 802, 823, 625, 719, 521, 510, 750, 542, 556, 556, 556, 365, 510, 500, 222, 278, 222, 906, 812, 556, 438, 559, 500, 552, 778, 556, 489, 411, 944, 722, 944, 722, 944, 722, 667, 500, 333, 333, 556, 1000, 1000, 552, 222, 222, 222, 222, 333, 333, 333, 556, 556, 350, 1000, 1000, 188, 354, 333, 333, 500, 333, 167, 365, 556, 556, 1094, 556, 885, 323, 1073, 1000, 768, 600, 834, 834, 834, 834, 1000, 500, 1000, 500, 1000, 500, 500, 494, 612, 823, 713, 584, 549, 713, 979, 719, 274, 549, 549, 583, 549, 549, 604, 584, 604, 604, 708, 625, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 729, 604, 604, 354, 354, 1000, 990, 990, 990, 990, 494, 604, 604, 604, 604, 354, 1021, 1052, 917, 750, 750, 531, 656, 594, 510, 500, 750, 750, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 222, 222, 294, 294, 324, 324, 316, 328, 398, 285];\nconst LiberationSansRegularMapping = [-1, -1, -1, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 402, 506, 507, 508, 509, 510, 511, 536, 537, 538, 539, 710, 711, 713, 728, 729, 730, 731, 732, 733, 900, 901, 902, 903, 904, 905, 906, 908, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1138, 1139, 1168, 1169, 7808, 7809, 7810, 7811, 7812, 7813, 7922, 7923, 8208, 8209, 8211, 8212, 8213, 8215, 8216, 8217, 8218, 8219, 8220, 8221, 8222, 8224, 8225, 8226, 8230, 8240, 8242, 8243, 8249, 8250, 8252, 8254, 8260, 8319, 8355, 8356, 8359, 8364, 8453, 8467, 8470, 8482, 8486, 8494, 8539, 8540, 8541, 8542, 8592, 8593, 8594, 8595, 8596, 8597, 8616, 8706, 8710, 8719, 8721, 8722, 8730, 8734, 8735, 8745, 8747, 8776, 8800, 8801, 8804, 8805, 8962, 8976, 8992, 8993, 9472, 9474, 9484, 9488, 9492, 9496, 9500, 9508, 9516, 9524, 9532, 9552, 9553, 9554, 9555, 9556, 9557, 9558, 9559, 9560, 9561, 9562, 9563, 9564, 9565, 9566, 9567, 9568, 9569, 9570, 9571, 9572, 9573, 9574, 9575, 9576, 9577, 9578, 9579, 9580, 9600, 9604, 9608, 9612, 9616, 9617, 9618, 9619, 9632, 9633, 9642, 9643, 9644, 9650, 9658, 9660, 9668, 9674, 9675, 9679, 9688, 9689, 9702, 9786, 9787, 9788, 9792, 9794, 9824, 9827, 9829, 9830, 9834, 9835, 9836, 61441, 61442, 61445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1];\n\n;// ./src/core/myriadpro_factors.js\nconst MyriadProBoldFactors = [1.36898, 1, 1, 0.72706, 0.80479, 0.83734, 0.98894, 0.99793, 0.9897, 0.93884, 0.86209, 0.94292, 0.94292, 1.16661, 1.02058, 0.93582, 0.96694, 0.93582, 1.19137, 0.99793, 0.99793, 0.99793, 0.99793, 0.99793, 0.99793, 0.99793, 0.99793, 0.99793, 0.99793, 0.78076, 0.78076, 1.02058, 1.02058, 1.02058, 0.72851, 0.78966, 0.90838, 0.83637, 0.82391, 0.96376, 0.80061, 0.86275, 0.8768, 0.95407, 1.0258, 0.73901, 0.85022, 0.83655, 1.0156, 0.95546, 0.92179, 0.87107, 0.92179, 0.82114, 0.8096, 0.89713, 0.94438, 0.95353, 0.94083, 0.91905, 0.90406, 0.9446, 0.94292, 1.18777, 0.94292, 1.02058, 0.89903, 0.90088, 0.94938, 0.97898, 0.81093, 0.97571, 0.94938, 1.024, 0.9577, 0.95933, 0.98621, 1.0474, 0.97455, 0.98981, 0.9672, 0.95933, 0.9446, 0.97898, 0.97407, 0.97646, 0.78036, 1.10208, 0.95442, 0.95298, 0.97579, 0.9332, 0.94039, 0.938, 0.80687, 1.01149, 0.80687, 1.02058, 0.80479, 0.99793, 0.99793, 0.99793, 0.99793, 1.01149, 1.00872, 0.90088, 0.91882, 1.0213, 0.8361, 1.02058, 0.62295, 0.54324, 0.89022, 1.08595, 1, 1, 0.90088, 1, 0.97455, 0.93582, 0.90088, 1, 1.05686, 0.8361, 0.99642, 0.99642, 0.99642, 0.72851, 0.90838, 0.90838, 0.90838, 0.90838, 0.90838, 0.90838, 0.868, 0.82391, 0.80061, 0.80061, 0.80061, 0.80061, 1.0258, 1.0258, 1.0258, 1.0258, 0.97484, 0.95546, 0.92179, 0.92179, 0.92179, 0.92179, 0.92179, 1.02058, 0.92179, 0.94438, 0.94438, 0.94438, 0.94438, 0.90406, 0.86958, 0.98225, 0.94938, 0.94938, 0.94938, 0.94938, 0.94938, 0.94938, 0.9031, 0.81093, 0.94938, 0.94938, 0.94938, 0.94938, 0.98621, 0.98621, 0.98621, 0.98621, 0.93969, 0.95933, 0.9446, 0.9446, 0.9446, 0.9446, 0.9446, 1.08595, 0.9446, 0.95442, 0.95442, 0.95442, 0.95442, 0.94039, 0.97898, 0.94039, 0.90838, 0.94938, 0.90838, 0.94938, 0.90838, 0.94938, 0.82391, 0.81093, 0.82391, 0.81093, 0.82391, 0.81093, 0.82391, 0.81093, 0.96376, 0.84313, 0.97484, 0.97571, 0.80061, 0.94938, 0.80061, 0.94938, 0.80061, 0.94938, 0.80061, 0.94938, 0.80061, 0.94938, 0.8768, 0.9577, 0.8768, 0.9577, 0.8768, 0.9577, 1, 1, 0.95407, 0.95933, 0.97069, 0.95933, 1.0258, 0.98621, 1.0258, 0.98621, 1.0258, 0.98621, 1.0258, 0.98621, 1.0258, 0.98621, 0.887, 1.01591, 0.73901, 1.0474, 1, 1, 0.97455, 0.83655, 0.98981, 1, 1, 0.83655, 0.73977, 0.83655, 0.73903, 0.84638, 1.033, 0.95546, 0.95933, 1, 1, 0.95546, 0.95933, 0.8271, 0.95417, 0.95933, 0.92179, 0.9446, 0.92179, 0.9446, 0.92179, 0.9446, 0.936, 0.91964, 0.82114, 0.97646, 1, 1, 0.82114, 0.97646, 0.8096, 0.78036, 0.8096, 0.78036, 1, 1, 0.8096, 0.78036, 1, 1, 0.89713, 0.77452, 0.89713, 1.10208, 0.94438, 0.95442, 0.94438, 0.95442, 0.94438, 0.95442, 0.94438, 0.95442, 0.94438, 0.95442, 0.94438, 0.95442, 0.94083, 0.97579, 0.90406, 0.94039, 0.90406, 0.9446, 0.938, 0.9446, 0.938, 0.9446, 0.938, 1, 0.99793, 0.90838, 0.94938, 0.868, 0.9031, 0.92179, 0.9446, 1, 1, 0.89713, 1.10208, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90989, 0.9358, 0.91945, 0.83181, 0.75261, 0.87992, 0.82976, 0.96034, 0.83689, 0.97268, 1.0078, 0.90838, 0.83637, 0.8019, 0.90157, 0.80061, 0.9446, 0.95407, 0.92436, 1.0258, 0.85022, 0.97153, 1.0156, 0.95546, 0.89192, 0.92179, 0.92361, 0.87107, 0.96318, 0.89713, 0.93704, 0.95638, 0.91905, 0.91709, 0.92796, 1.0258, 0.93704, 0.94836, 1.0373, 0.95933, 1.0078, 0.95871, 0.94836, 0.96174, 0.92601, 0.9498, 0.98607, 0.95776, 0.95933, 1.05453, 1.0078, 0.98275, 0.9314, 0.95617, 0.91701, 1.05993, 0.9446, 0.78367, 0.9553, 1, 0.86832, 1.0128, 0.95871, 0.99394, 0.87548, 0.96361, 0.86774, 1.0078, 0.95871, 0.9446, 0.95871, 0.86774, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.94083, 0.97579, 0.94083, 0.97579, 0.94083, 0.97579, 0.90406, 0.94039, 0.96694, 1, 0.89903, 1, 1, 1, 0.93582, 0.93582, 0.93582, 1, 0.908, 0.908, 0.918, 0.94219, 0.94219, 0.96544, 1, 1.285, 1, 1, 0.81079, 0.81079, 1, 1, 0.74854, 1, 1, 1, 1, 0.99793, 1, 1, 1, 0.65, 1, 1.36145, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.17173, 1, 0.80535, 0.76169, 1.02058, 1.0732, 1.05486, 1, 1, 1.30692, 1.08595, 1.08595, 1, 1.08595, 1.08595, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.16161, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];\nconst MyriadProBoldMetrics = {\n  lineHeight: 1.2,\n  lineGap: 0.2\n};\nconst MyriadProBoldItalicFactors = [1.36898, 1, 1, 0.66227, 0.80779, 0.81625, 0.97276, 0.97276, 0.97733, 0.92222, 0.83266, 0.94292, 0.94292, 1.16148, 1.02058, 0.93582, 0.96694, 0.93582, 1.17337, 0.97276, 0.97276, 0.97276, 0.97276, 0.97276, 0.97276, 0.97276, 0.97276, 0.97276, 0.97276, 0.78076, 0.78076, 1.02058, 1.02058, 1.02058, 0.71541, 0.76813, 0.85576, 0.80591, 0.80729, 0.94299, 0.77512, 0.83655, 0.86523, 0.92222, 0.98621, 0.71743, 0.81698, 0.79726, 0.98558, 0.92222, 0.90637, 0.83809, 0.90637, 0.80729, 0.76463, 0.86275, 0.90699, 0.91605, 0.9154, 0.85308, 0.85458, 0.90531, 0.94292, 1.21296, 0.94292, 1.02058, 0.89903, 1.18616, 0.99613, 0.91677, 0.78216, 0.91677, 0.90083, 0.98796, 0.9135, 0.92168, 0.95381, 0.98981, 0.95298, 0.95381, 0.93459, 0.92168, 0.91513, 0.92004, 0.91677, 0.95077, 0.748, 1.04502, 0.91677, 0.92061, 0.94236, 0.89544, 0.89364, 0.9, 0.80687, 0.8578, 0.80687, 1.02058, 0.80779, 0.97276, 0.97276, 0.97276, 0.97276, 0.8578, 0.99973, 1.18616, 0.91339, 1.08074, 0.82891, 1.02058, 0.55509, 0.71526, 0.89022, 1.08595, 1, 1, 1.18616, 1, 0.96736, 0.93582, 1.18616, 1, 1.04864, 0.82711, 0.99043, 0.99043, 0.99043, 0.71541, 0.85576, 0.85576, 0.85576, 0.85576, 0.85576, 0.85576, 0.845, 0.80729, 0.77512, 0.77512, 0.77512, 0.77512, 0.98621, 0.98621, 0.98621, 0.98621, 0.95961, 0.92222, 0.90637, 0.90637, 0.90637, 0.90637, 0.90637, 1.02058, 0.90251, 0.90699, 0.90699, 0.90699, 0.90699, 0.85458, 0.83659, 0.94951, 0.99613, 0.99613, 0.99613, 0.99613, 0.99613, 0.99613, 0.85811, 0.78216, 0.90083, 0.90083, 0.90083, 0.90083, 0.95381, 0.95381, 0.95381, 0.95381, 0.9135, 0.92168, 0.91513, 0.91513, 0.91513, 0.91513, 0.91513, 1.08595, 0.91677, 0.91677, 0.91677, 0.91677, 0.91677, 0.89364, 0.92332, 0.89364, 0.85576, 0.99613, 0.85576, 0.99613, 0.85576, 0.99613, 0.80729, 0.78216, 0.80729, 0.78216, 0.80729, 0.78216, 0.80729, 0.78216, 0.94299, 0.76783, 0.95961, 0.91677, 0.77512, 0.90083, 0.77512, 0.90083, 0.77512, 0.90083, 0.77512, 0.90083, 0.77512, 0.90083, 0.86523, 0.9135, 0.86523, 0.9135, 0.86523, 0.9135, 1, 1, 0.92222, 0.92168, 0.92222, 0.92168, 0.98621, 0.95381, 0.98621, 0.95381, 0.98621, 0.95381, 0.98621, 0.95381, 0.98621, 0.95381, 0.86036, 0.97096, 0.71743, 0.98981, 1, 1, 0.95298, 0.79726, 0.95381, 1, 1, 0.79726, 0.6894, 0.79726, 0.74321, 0.81691, 1.0006, 0.92222, 0.92168, 1, 1, 0.92222, 0.92168, 0.79464, 0.92098, 0.92168, 0.90637, 0.91513, 0.90637, 0.91513, 0.90637, 0.91513, 0.909, 0.87514, 0.80729, 0.95077, 1, 1, 0.80729, 0.95077, 0.76463, 0.748, 0.76463, 0.748, 1, 1, 0.76463, 0.748, 1, 1, 0.86275, 0.72651, 0.86275, 1.04502, 0.90699, 0.91677, 0.90699, 0.91677, 0.90699, 0.91677, 0.90699, 0.91677, 0.90699, 0.91677, 0.90699, 0.91677, 0.9154, 0.94236, 0.85458, 0.89364, 0.85458, 0.90531, 0.9, 0.90531, 0.9, 0.90531, 0.9, 1, 0.97276, 0.85576, 0.99613, 0.845, 0.85811, 0.90251, 0.91677, 1, 1, 0.86275, 1.04502, 1.18616, 1.18616, 1.18616, 1.18616, 1.18616, 1.18616, 1.18616, 1.18616, 1.18616, 1.00899, 1.30628, 0.85576, 0.80178, 0.66862, 0.7927, 0.69323, 0.88127, 0.72459, 0.89711, 0.95381, 0.85576, 0.80591, 0.7805, 0.94729, 0.77512, 0.90531, 0.92222, 0.90637, 0.98621, 0.81698, 0.92655, 0.98558, 0.92222, 0.85359, 0.90637, 0.90976, 0.83809, 0.94523, 0.86275, 0.83509, 0.93157, 0.85308, 0.83392, 0.92346, 0.98621, 0.83509, 0.92886, 0.91324, 0.92168, 0.95381, 0.90646, 0.92886, 0.90557, 0.86847, 0.90276, 0.91324, 0.86842, 0.92168, 0.99531, 0.95381, 0.9224, 0.85408, 0.92699, 0.86847, 1.0051, 0.91513, 0.80487, 0.93481, 1, 0.88159, 1.05214, 0.90646, 0.97355, 0.81539, 0.89398, 0.85923, 0.95381, 0.90646, 0.91513, 0.90646, 0.85923, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9154, 0.94236, 0.9154, 0.94236, 0.9154, 0.94236, 0.85458, 0.89364, 0.96694, 1, 0.89903, 1, 1, 1, 0.91782, 0.91782, 0.91782, 1, 0.896, 0.896, 0.896, 0.9332, 0.9332, 0.95973, 1, 1.26, 1, 1, 0.80479, 0.80178, 1, 1, 0.85633, 1, 1, 1, 1, 0.97276, 1, 1, 1, 0.698, 1, 1.36145, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.14542, 1, 0.79199, 0.78694, 1.02058, 1.03493, 1.05486, 1, 1, 1.23026, 1.08595, 1.08595, 1, 1.08595, 1.08595, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.20006, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];\nconst MyriadProBoldItalicMetrics = {\n  lineHeight: 1.2,\n  lineGap: 0.2\n};\nconst MyriadProItalicFactors = [1.36898, 1, 1, 0.65507, 0.84943, 0.85639, 0.88465, 0.88465, 0.86936, 0.88307, 0.86948, 0.85283, 0.85283, 1.06383, 1.02058, 0.75945, 0.9219, 0.75945, 1.17337, 0.88465, 0.88465, 0.88465, 0.88465, 0.88465, 0.88465, 0.88465, 0.88465, 0.88465, 0.88465, 0.75945, 0.75945, 1.02058, 1.02058, 1.02058, 0.69046, 0.70926, 0.85158, 0.77812, 0.76852, 0.89591, 0.70466, 0.76125, 0.80094, 0.86822, 0.83864, 0.728, 0.77212, 0.79475, 0.93637, 0.87514, 0.8588, 0.76013, 0.8588, 0.72421, 0.69866, 0.77598, 0.85991, 0.80811, 0.87832, 0.78112, 0.77512, 0.8562, 1.0222, 1.18417, 1.0222, 1.27014, 0.89903, 1.15012, 0.93859, 0.94399, 0.846, 0.94399, 0.81453, 1.0186, 0.94219, 0.96017, 1.03075, 1.02175, 0.912, 1.03075, 0.96998, 0.96017, 0.93859, 0.94399, 0.94399, 0.95493, 0.746, 1.12658, 0.94578, 0.91, 0.979, 0.882, 0.882, 0.83, 0.85034, 0.83537, 0.85034, 1.02058, 0.70869, 0.88465, 0.88465, 0.88465, 0.88465, 0.83537, 0.90083, 1.15012, 0.9161, 0.94565, 0.73541, 1.02058, 0.53609, 0.69353, 0.79519, 1.08595, 1, 1, 1.15012, 1, 0.91974, 0.75945, 1.15012, 1, 0.9446, 0.73361, 0.9005, 0.9005, 0.9005, 0.62864, 0.85158, 0.85158, 0.85158, 0.85158, 0.85158, 0.85158, 0.773, 0.76852, 0.70466, 0.70466, 0.70466, 0.70466, 0.83864, 0.83864, 0.83864, 0.83864, 0.90561, 0.87514, 0.8588, 0.8588, 0.8588, 0.8588, 0.8588, 1.02058, 0.85751, 0.85991, 0.85991, 0.85991, 0.85991, 0.77512, 0.76013, 0.88075, 0.93859, 0.93859, 0.93859, 0.93859, 0.93859, 0.93859, 0.8075, 0.846, 0.81453, 0.81453, 0.81453, 0.81453, 0.82424, 0.82424, 0.82424, 0.82424, 0.9278, 0.96017, 0.93859, 0.93859, 0.93859, 0.93859, 0.93859, 1.08595, 0.8562, 0.94578, 0.94578, 0.94578, 0.94578, 0.882, 0.94578, 0.882, 0.85158, 0.93859, 0.85158, 0.93859, 0.85158, 0.93859, 0.76852, 0.846, 0.76852, 0.846, 0.76852, 0.846, 0.76852, 0.846, 0.89591, 0.8544, 0.90561, 0.94399, 0.70466, 0.81453, 0.70466, 0.81453, 0.70466, 0.81453, 0.70466, 0.81453, 0.70466, 0.81453, 0.80094, 0.94219, 0.80094, 0.94219, 0.80094, 0.94219, 1, 1, 0.86822, 0.96017, 0.86822, 0.96017, 0.83864, 0.82424, 0.83864, 0.82424, 0.83864, 0.82424, 0.83864, 1.03075, 0.83864, 0.82424, 0.81402, 1.02738, 0.728, 1.02175, 1, 1, 0.912, 0.79475, 1.03075, 1, 1, 0.79475, 0.83911, 0.79475, 0.66266, 0.80553, 1.06676, 0.87514, 0.96017, 1, 1, 0.87514, 0.96017, 0.86865, 0.87396, 0.96017, 0.8588, 0.93859, 0.8588, 0.93859, 0.8588, 0.93859, 0.867, 0.84759, 0.72421, 0.95493, 1, 1, 0.72421, 0.95493, 0.69866, 0.746, 0.69866, 0.746, 1, 1, 0.69866, 0.746, 1, 1, 0.77598, 0.88417, 0.77598, 1.12658, 0.85991, 0.94578, 0.85991, 0.94578, 0.85991, 0.94578, 0.85991, 0.94578, 0.85991, 0.94578, 0.85991, 0.94578, 0.87832, 0.979, 0.77512, 0.882, 0.77512, 0.8562, 0.83, 0.8562, 0.83, 0.8562, 0.83, 1, 0.88465, 0.85158, 0.93859, 0.773, 0.8075, 0.85751, 0.8562, 1, 1, 0.77598, 1.12658, 1.15012, 1.15012, 1.15012, 1.15012, 1.15012, 1.15313, 1.15012, 1.15012, 1.15012, 1.08106, 1.03901, 0.85158, 0.77025, 0.62264, 0.7646, 0.65351, 0.86026, 0.69461, 0.89947, 1.03075, 0.85158, 0.77812, 0.76449, 0.88836, 0.70466, 0.8562, 0.86822, 0.8588, 0.83864, 0.77212, 0.85308, 0.93637, 0.87514, 0.82352, 0.8588, 0.85701, 0.76013, 0.89058, 0.77598, 0.8156, 0.82565, 0.78112, 0.77899, 0.89386, 0.83864, 0.8156, 0.9486, 0.92388, 0.96186, 1.03075, 0.91123, 0.9486, 0.93298, 0.878, 0.93942, 0.92388, 0.84596, 0.96186, 0.95119, 1.03075, 0.922, 0.88787, 0.95829, 0.88, 0.93559, 0.93859, 0.78815, 0.93758, 1, 0.89217, 1.03737, 0.91123, 0.93969, 0.77487, 0.85769, 0.86799, 1.03075, 0.91123, 0.93859, 0.91123, 0.86799, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.87832, 0.979, 0.87832, 0.979, 0.87832, 0.979, 0.77512, 0.882, 0.9219, 1, 0.89903, 1, 1, 1, 0.87321, 0.87321, 0.87321, 1, 1.027, 1.027, 1.027, 0.86847, 0.86847, 0.79121, 1, 1.124, 1, 1, 0.73572, 0.73572, 1, 1, 0.85034, 1, 1, 1, 1, 0.88465, 1, 1, 1, 0.669, 1, 1.36145, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.04828, 1, 0.74948, 0.75187, 1.02058, 0.98391, 1.02119, 1, 1, 1.06233, 1.08595, 1.08595, 1, 1.08595, 1.08595, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.05233, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];\nconst MyriadProItalicMetrics = {\n  lineHeight: 1.2,\n  lineGap: 0.2\n};\nconst MyriadProRegularFactors = [1.36898, 1, 1, 0.76305, 0.82784, 0.94935, 0.89364, 0.92241, 0.89073, 0.90706, 0.98472, 0.85283, 0.85283, 1.0664, 1.02058, 0.74505, 0.9219, 0.74505, 1.23456, 0.92241, 0.92241, 0.92241, 0.92241, 0.92241, 0.92241, 0.92241, 0.92241, 0.92241, 0.92241, 0.74505, 0.74505, 1.02058, 1.02058, 1.02058, 0.73002, 0.72601, 0.91755, 0.8126, 0.80314, 0.92222, 0.73764, 0.79726, 0.83051, 0.90284, 0.86023, 0.74, 0.8126, 0.84869, 0.96518, 0.91115, 0.8858, 0.79761, 0.8858, 0.74498, 0.73914, 0.81363, 0.89591, 0.83659, 0.89633, 0.85608, 0.8111, 0.90531, 1.0222, 1.22736, 1.0222, 1.27014, 0.89903, 0.90088, 0.86667, 1.0231, 0.896, 1.01411, 0.90083, 1.05099, 1.00512, 0.99793, 1.05326, 1.09377, 0.938, 1.06226, 1.00119, 0.99793, 0.98714, 1.0231, 1.01231, 0.98196, 0.792, 1.19137, 0.99074, 0.962, 1.01915, 0.926, 0.942, 0.856, 0.85034, 0.92006, 0.85034, 1.02058, 0.69067, 0.92241, 0.92241, 0.92241, 0.92241, 0.92006, 0.9332, 0.90088, 0.91882, 0.93484, 0.75339, 1.02058, 0.56866, 0.54324, 0.79519, 1.08595, 1, 1, 0.90088, 1, 0.95325, 0.74505, 0.90088, 1, 0.97198, 0.75339, 0.91009, 0.91009, 0.91009, 0.66466, 0.91755, 0.91755, 0.91755, 0.91755, 0.91755, 0.91755, 0.788, 0.80314, 0.73764, 0.73764, 0.73764, 0.73764, 0.86023, 0.86023, 0.86023, 0.86023, 0.92915, 0.91115, 0.8858, 0.8858, 0.8858, 0.8858, 0.8858, 1.02058, 0.8858, 0.89591, 0.89591, 0.89591, 0.89591, 0.8111, 0.79611, 0.89713, 0.86667, 0.86667, 0.86667, 0.86667, 0.86667, 0.86667, 0.86936, 0.896, 0.90083, 0.90083, 0.90083, 0.90083, 0.84224, 0.84224, 0.84224, 0.84224, 0.97276, 0.99793, 0.98714, 0.98714, 0.98714, 0.98714, 0.98714, 1.08595, 0.89876, 0.99074, 0.99074, 0.99074, 0.99074, 0.942, 1.0231, 0.942, 0.91755, 0.86667, 0.91755, 0.86667, 0.91755, 0.86667, 0.80314, 0.896, 0.80314, 0.896, 0.80314, 0.896, 0.80314, 0.896, 0.92222, 0.93372, 0.92915, 1.01411, 0.73764, 0.90083, 0.73764, 0.90083, 0.73764, 0.90083, 0.73764, 0.90083, 0.73764, 0.90083, 0.83051, 1.00512, 0.83051, 1.00512, 0.83051, 1.00512, 1, 1, 0.90284, 0.99793, 0.90976, 0.99793, 0.86023, 0.84224, 0.86023, 0.84224, 0.86023, 0.84224, 0.86023, 1.05326, 0.86023, 0.84224, 0.82873, 1.07469, 0.74, 1.09377, 1, 1, 0.938, 0.84869, 1.06226, 1, 1, 0.84869, 0.83704, 0.84869, 0.81441, 0.85588, 1.08927, 0.91115, 0.99793, 1, 1, 0.91115, 0.99793, 0.91887, 0.90991, 0.99793, 0.8858, 0.98714, 0.8858, 0.98714, 0.8858, 0.98714, 0.894, 0.91434, 0.74498, 0.98196, 1, 1, 0.74498, 0.98196, 0.73914, 0.792, 0.73914, 0.792, 1, 1, 0.73914, 0.792, 1, 1, 0.81363, 0.904, 0.81363, 1.19137, 0.89591, 0.99074, 0.89591, 0.99074, 0.89591, 0.99074, 0.89591, 0.99074, 0.89591, 0.99074, 0.89591, 0.99074, 0.89633, 1.01915, 0.8111, 0.942, 0.8111, 0.90531, 0.856, 0.90531, 0.856, 0.90531, 0.856, 1, 0.92241, 0.91755, 0.86667, 0.788, 0.86936, 0.8858, 0.89876, 1, 1, 0.81363, 1.19137, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90388, 1.03901, 0.92138, 0.78105, 0.7154, 0.86169, 0.80513, 0.94007, 0.82528, 0.98612, 1.06226, 0.91755, 0.8126, 0.81884, 0.92819, 0.73764, 0.90531, 0.90284, 0.8858, 0.86023, 0.8126, 0.91172, 0.96518, 0.91115, 0.83089, 0.8858, 0.87791, 0.79761, 0.89297, 0.81363, 0.88157, 0.89992, 0.85608, 0.81992, 0.94307, 0.86023, 0.88157, 0.95308, 0.98699, 0.99793, 1.06226, 0.95817, 0.95308, 0.97358, 0.928, 0.98088, 0.98699, 0.92761, 0.99793, 0.96017, 1.06226, 0.986, 0.944, 0.95978, 0.938, 0.96705, 0.98714, 0.80442, 0.98972, 1, 0.89762, 1.04552, 0.95817, 0.99007, 0.87064, 0.91879, 0.88888, 1.06226, 0.95817, 0.98714, 0.95817, 0.88888, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.89633, 1.01915, 0.89633, 1.01915, 0.89633, 1.01915, 0.8111, 0.942, 0.9219, 1, 0.89903, 1, 1, 1, 0.93173, 0.93173, 0.93173, 1, 1.06304, 1.06304, 1.06904, 0.89903, 0.89903, 0.80549, 1, 1.156, 1, 1, 0.76575, 0.76575, 1, 1, 0.72458, 1, 1, 1, 1, 0.92241, 1, 1, 1, 0.619, 1, 1.36145, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.07257, 1, 0.74705, 0.71119, 1.02058, 1.024, 1.02119, 1, 1, 1.1536, 1.08595, 1.08595, 1, 1.08595, 1.08595, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.05638, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];\nconst MyriadProRegularMetrics = {\n  lineHeight: 1.2,\n  lineGap: 0.2\n};\n\n;// ./src/core/segoeui_factors.js\nconst SegoeuiBoldFactors = [1.76738, 1, 1, 0.99297, 0.9824, 1.04016, 1.06497, 1.03424, 0.97529, 1.17647, 1.23203, 1.1085, 1.1085, 1.16939, 1.2107, 0.9754, 1.21408, 0.9754, 1.59578, 1.03424, 1.03424, 1.03424, 1.03424, 1.03424, 1.03424, 1.03424, 1.03424, 1.03424, 1.03424, 0.81378, 0.81378, 1.2107, 1.2107, 1.2107, 0.71703, 0.97847, 0.97363, 0.88776, 0.8641, 1.02096, 0.79795, 0.85132, 0.914, 1.06085, 1.1406, 0.8007, 0.89858, 0.83693, 1.14889, 1.09398, 0.97489, 0.92094, 0.97489, 0.90399, 0.84041, 0.95923, 1.00135, 1, 1.06467, 0.98243, 0.90996, 0.99361, 1.1085, 1.56942, 1.1085, 1.2107, 0.74627, 0.94282, 0.96752, 1.01519, 0.86304, 1.01359, 0.97278, 1.15103, 1.01359, 0.98561, 1.02285, 1.02285, 1.00527, 1.02285, 1.0302, 0.99041, 1.0008, 1.01519, 1.01359, 1.02258, 0.79104, 1.16862, 0.99041, 0.97454, 1.02511, 0.99298, 0.96752, 0.95801, 0.94856, 1.16579, 0.94856, 1.2107, 0.9824, 1.03424, 1.03424, 1, 1.03424, 1.16579, 0.8727, 1.3871, 1.18622, 1.10818, 1.04478, 1.2107, 1.18622, 0.75155, 0.94994, 1.28826, 1.21408, 1.21408, 0.91056, 1, 0.91572, 0.9754, 0.64663, 1.18328, 1.24866, 1.04478, 1.14169, 1.15749, 1.17389, 0.71703, 0.97363, 0.97363, 0.97363, 0.97363, 0.97363, 0.97363, 0.93506, 0.8641, 0.79795, 0.79795, 0.79795, 0.79795, 1.1406, 1.1406, 1.1406, 1.1406, 1.02096, 1.09398, 0.97426, 0.97426, 0.97426, 0.97426, 0.97426, 1.2107, 0.97489, 1.00135, 1.00135, 1.00135, 1.00135, 0.90996, 0.92094, 1.02798, 0.96752, 0.96752, 0.96752, 0.96752, 0.96752, 0.96752, 0.93136, 0.86304, 0.97278, 0.97278, 0.97278, 0.97278, 1.02285, 1.02285, 1.02285, 1.02285, 0.97122, 0.99041, 1, 1, 1, 1, 1, 1.28826, 1.0008, 0.99041, 0.99041, 0.99041, 0.99041, 0.96752, 1.01519, 0.96752, 0.97363, 0.96752, 0.97363, 0.96752, 0.97363, 0.96752, 0.8641, 0.86304, 0.8641, 0.86304, 0.8641, 0.86304, 0.8641, 0.86304, 1.02096, 1.03057, 1.02096, 1.03517, 0.79795, 0.97278, 0.79795, 0.97278, 0.79795, 0.97278, 0.79795, 0.97278, 0.79795, 0.97278, 0.914, 1.01359, 0.914, 1.01359, 0.914, 1.01359, 1, 1, 1.06085, 0.98561, 1.06085, 1.00879, 1.1406, 1.02285, 1.1406, 1.02285, 1.1406, 1.02285, 1.1406, 1.02285, 1.1406, 1.02285, 0.97138, 1.08692, 0.8007, 1.02285, 1, 1, 1.00527, 0.83693, 1.02285, 1, 1, 0.83693, 0.9455, 0.83693, 0.90418, 0.83693, 1.13005, 1.09398, 0.99041, 1, 1, 1.09398, 0.99041, 0.96692, 1.09251, 0.99041, 0.97489, 1.0008, 0.97489, 1.0008, 0.97489, 1.0008, 0.93994, 0.97931, 0.90399, 1.02258, 1, 1, 0.90399, 1.02258, 0.84041, 0.79104, 0.84041, 0.79104, 0.84041, 0.79104, 0.84041, 0.79104, 1, 1, 0.95923, 1.07034, 0.95923, 1.16862, 1.00135, 0.99041, 1.00135, 0.99041, 1.00135, 0.99041, 1.00135, 0.99041, 1.00135, 0.99041, 1.00135, 0.99041, 1.06467, 1.02511, 0.90996, 0.96752, 0.90996, 0.99361, 0.95801, 0.99361, 0.95801, 0.99361, 0.95801, 1.07733, 1.03424, 0.97363, 0.96752, 0.93506, 0.93136, 0.97489, 1.0008, 1, 1, 0.95923, 1.16862, 1.15103, 1.15103, 1.01173, 1.03959, 0.75953, 0.81378, 0.79912, 1.15103, 1.21994, 0.95161, 0.87815, 1.01149, 0.81525, 0.7676, 0.98167, 1.01134, 1.02546, 0.84097, 1.03089, 1.18102, 0.97363, 0.88776, 0.85134, 0.97826, 0.79795, 0.99361, 1.06085, 0.97489, 1.1406, 0.89858, 1.0388, 1.14889, 1.09398, 0.86039, 0.97489, 1.0595, 0.92094, 0.94793, 0.95923, 0.90996, 0.99346, 0.98243, 1.02112, 0.95493, 1.1406, 0.90996, 1.03574, 1.02597, 1.0008, 1.18102, 1.06628, 1.03574, 1.0192, 1.01932, 1.00886, 0.97531, 1.0106, 1.0008, 1.13189, 1.18102, 1.02277, 0.98683, 1.0016, 0.99561, 1.07237, 1.0008, 0.90434, 0.99921, 0.93803, 0.8965, 1.23085, 1.06628, 1.04983, 0.96268, 1.0499, 0.98439, 1.18102, 1.06628, 1.0008, 1.06628, 0.98439, 0.79795, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.09466, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.97278, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.02065, 1, 1, 1, 1, 1, 1, 1.06467, 1.02511, 1.06467, 1.02511, 1.06467, 1.02511, 0.90996, 0.96752, 1, 1.21408, 0.89903, 1, 1, 0.75155, 1.04394, 1.04394, 1.04394, 1.04394, 0.98633, 0.98633, 0.98633, 0.73047, 0.73047, 1.20642, 0.91211, 1.25635, 1.222, 1.02956, 1.03372, 1.03372, 0.96039, 1.24633, 1, 1.12454, 0.93503, 1.03424, 1.19687, 1.03424, 1, 1, 1, 0.771, 1, 1, 1.15749, 1.15749, 1.15749, 1.10948, 0.86279, 0.94434, 0.86279, 0.94434, 0.86182, 1, 1, 1.16897, 1, 0.96085, 0.90137, 1.2107, 1.18416, 1.13973, 0.69825, 0.9716, 2.10339, 1.29004, 1.29004, 1.21172, 1.29004, 1.29004, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.42603, 1, 0.99862, 0.99862, 1, 0.87025, 0.87025, 0.87025, 0.87025, 1.18874, 1.42603, 1, 1.42603, 1.42603, 0.99862, 1, 1, 1, 1, 1, 1.2886, 1.04315, 1.15296, 1.34163, 1, 1, 1, 1.09193, 1.09193, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];\nconst SegoeuiBoldMetrics = {\n  lineHeight: 1.33008,\n  lineGap: 0\n};\nconst SegoeuiBoldItalicFactors = [1.76738, 1, 1, 0.98946, 1.03959, 1.04016, 1.02809, 1.036, 0.97639, 1.10953, 1.23203, 1.11144, 1.11144, 1.16939, 1.21237, 0.9754, 1.21261, 0.9754, 1.59754, 1.036, 1.036, 1.036, 1.036, 1.036, 1.036, 1.036, 1.036, 1.036, 1.036, 0.81378, 0.81378, 1.21237, 1.21237, 1.21237, 0.73541, 0.97847, 0.97363, 0.89723, 0.87897, 1.0426, 0.79429, 0.85292, 0.91149, 1.05815, 1.1406, 0.79631, 0.90128, 0.83853, 1.04396, 1.10615, 0.97552, 0.94436, 0.97552, 0.88641, 0.80527, 0.96083, 1.00135, 1, 1.06777, 0.9817, 0.91142, 0.99361, 1.11144, 1.57293, 1.11144, 1.21237, 0.74627, 1.31818, 1.06585, 0.97042, 0.83055, 0.97042, 0.93503, 1.1261, 0.97042, 0.97922, 1.14236, 0.94552, 1.01054, 1.14236, 1.02471, 0.97922, 0.94165, 0.97042, 0.97042, 1.0276, 0.78929, 1.1261, 0.97922, 0.95874, 1.02197, 0.98507, 0.96752, 0.97168, 0.95107, 1.16579, 0.95107, 1.21237, 1.03959, 1.036, 1.036, 1, 1.036, 1.16579, 0.87357, 1.31818, 1.18754, 1.26781, 1.05356, 1.21237, 1.18622, 0.79487, 0.94994, 1.29004, 1.24047, 1.24047, 1.31818, 1, 0.91484, 0.9754, 1.31818, 1.1349, 1.24866, 1.05356, 1.13934, 1.15574, 1.17389, 0.73541, 0.97363, 0.97363, 0.97363, 0.97363, 0.97363, 0.97363, 0.94385, 0.87897, 0.79429, 0.79429, 0.79429, 0.79429, 1.1406, 1.1406, 1.1406, 1.1406, 1.0426, 1.10615, 0.97552, 0.97552, 0.97552, 0.97552, 0.97552, 1.21237, 0.97552, 1.00135, 1.00135, 1.00135, 1.00135, 0.91142, 0.94436, 0.98721, 1.06585, 1.06585, 1.06585, 1.06585, 1.06585, 1.06585, 0.96705, 0.83055, 0.93503, 0.93503, 0.93503, 0.93503, 1.14236, 1.14236, 1.14236, 1.14236, 0.93125, 0.97922, 0.94165, 0.94165, 0.94165, 0.94165, 0.94165, 1.29004, 0.94165, 0.97922, 0.97922, 0.97922, 0.97922, 0.96752, 0.97042, 0.96752, 0.97363, 1.06585, 0.97363, 1.06585, 0.97363, 1.06585, 0.87897, 0.83055, 0.87897, 0.83055, 0.87897, 0.83055, 0.87897, 0.83055, 1.0426, 1.0033, 1.0426, 0.97042, 0.79429, 0.93503, 0.79429, 0.93503, 0.79429, 0.93503, 0.79429, 0.93503, 0.79429, 0.93503, 0.91149, 0.97042, 0.91149, 0.97042, 0.91149, 0.97042, 1, 1, 1.05815, 0.97922, 1.05815, 0.97922, 1.1406, 1.14236, 1.1406, 1.14236, 1.1406, 1.14236, 1.1406, 1.14236, 1.1406, 1.14236, 0.97441, 1.04302, 0.79631, 1.01582, 1, 1, 1.01054, 0.83853, 1.14236, 1, 1, 0.83853, 1.09125, 0.83853, 0.90418, 0.83853, 1.19508, 1.10615, 0.97922, 1, 1, 1.10615, 0.97922, 1.01034, 1.10466, 0.97922, 0.97552, 0.94165, 0.97552, 0.94165, 0.97552, 0.94165, 0.91602, 0.91981, 0.88641, 1.0276, 1, 1, 0.88641, 1.0276, 0.80527, 0.78929, 0.80527, 0.78929, 0.80527, 0.78929, 0.80527, 0.78929, 1, 1, 0.96083, 1.05403, 0.95923, 1.16862, 1.00135, 0.97922, 1.00135, 0.97922, 1.00135, 0.97922, 1.00135, 0.97922, 1.00135, 0.97922, 1.00135, 0.97922, 1.06777, 1.02197, 0.91142, 0.96752, 0.91142, 0.99361, 0.97168, 0.99361, 0.97168, 0.99361, 0.97168, 1.23199, 1.036, 0.97363, 1.06585, 0.94385, 0.96705, 0.97552, 0.94165, 1, 1, 0.96083, 1.1261, 1.31818, 1.31818, 1.31818, 1.31818, 1.31818, 1.31818, 1.31818, 1.31818, 1.31818, 0.95161, 1.27126, 1.00811, 0.83284, 0.77702, 0.99137, 0.95253, 1.0347, 0.86142, 1.07205, 1.14236, 0.97363, 0.89723, 0.86869, 1.09818, 0.79429, 0.99361, 1.05815, 0.97552, 1.1406, 0.90128, 1.06662, 1.04396, 1.10615, 0.84918, 0.97552, 1.04694, 0.94436, 0.98015, 0.96083, 0.91142, 1.00356, 0.9817, 1.01945, 0.98999, 1.1406, 0.91142, 1.04961, 0.9898, 1.00639, 1.14236, 1.07514, 1.04961, 0.99607, 1.02897, 1.008, 0.9898, 0.95134, 1.00639, 1.11121, 1.14236, 1.00518, 0.97981, 1.02186, 1, 1.08578, 0.94165, 0.99314, 0.98387, 0.93028, 0.93377, 1.35125, 1.07514, 1.10687, 0.93491, 1.04232, 1.00351, 1.14236, 1.07514, 0.94165, 1.07514, 1.00351, 0.79429, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.09097, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.93503, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.96609, 1, 1, 1, 1, 1, 1, 1.06777, 1.02197, 1.06777, 1.02197, 1.06777, 1.02197, 0.91142, 0.96752, 1, 1.21261, 0.89903, 1, 1, 0.75155, 1.04745, 1.04745, 1.04745, 1.04394, 0.98633, 0.98633, 0.98633, 0.72959, 0.72959, 1.20502, 0.91406, 1.26514, 1.222, 1.02956, 1.03372, 1.03372, 0.96039, 1.24633, 1, 1.09125, 0.93327, 1.03336, 1.16541, 1.036, 1, 1, 1, 0.771, 1, 1, 1.15574, 1.15574, 1.15574, 1.15574, 0.86364, 0.94434, 0.86279, 0.94434, 0.86224, 1, 1, 1.16798, 1, 0.96085, 0.90068, 1.21237, 1.18416, 1.13904, 0.69825, 0.9716, 2.10339, 1.29004, 1.29004, 1.21339, 1.29004, 1.29004, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.42603, 1, 0.99862, 0.99862, 1, 0.87025, 0.87025, 0.87025, 0.87025, 1.18775, 1.42603, 1, 1.42603, 1.42603, 0.99862, 1, 1, 1, 1, 1, 1.2886, 1.04315, 1.15296, 1.34163, 1, 1, 1, 1.13269, 1.13269, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];\nconst SegoeuiBoldItalicMetrics = {\n  lineHeight: 1.33008,\n  lineGap: 0\n};\nconst SegoeuiItalicFactors = [1.76738, 1, 1, 0.98946, 1.14763, 1.05365, 1.06234, 0.96927, 0.92586, 1.15373, 1.18414, 0.91349, 0.91349, 1.07403, 1.17308, 0.78383, 1.20088, 0.78383, 1.42531, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.78383, 0.78383, 1.17308, 1.17308, 1.17308, 0.77349, 0.94565, 0.94729, 0.85944, 0.88506, 0.9858, 0.74817, 0.80016, 0.88449, 0.98039, 0.95782, 0.69238, 0.89898, 0.83231, 0.98183, 1.03989, 0.96924, 0.86237, 0.96924, 0.80595, 0.74524, 0.86091, 0.95402, 0.94143, 0.98448, 0.8858, 0.83089, 0.93285, 1.0949, 1.39016, 1.0949, 1.45994, 0.74627, 1.04839, 0.97454, 0.97454, 0.87207, 0.97454, 0.87533, 1.06151, 0.97454, 1.00176, 1.16484, 1.08132, 0.98047, 1.16484, 1.02989, 1.01054, 0.96225, 0.97454, 0.97454, 1.06598, 0.79004, 1.16344, 1.00351, 0.94629, 0.9973, 0.91016, 0.96777, 0.9043, 0.91082, 0.92481, 0.91082, 1.17308, 0.95748, 0.96927, 0.96927, 1, 0.96927, 0.92481, 0.80597, 1.04839, 1.23393, 1.1781, 0.9245, 1.17308, 1.20808, 0.63218, 0.94261, 1.24822, 1.09971, 1.09971, 1.04839, 1, 0.85273, 0.78032, 1.04839, 1.09971, 1.22326, 0.9245, 1.09836, 1.13525, 1.15222, 0.70424, 0.94729, 0.94729, 0.94729, 0.94729, 0.94729, 0.94729, 0.85498, 0.88506, 0.74817, 0.74817, 0.74817, 0.74817, 0.95782, 0.95782, 0.95782, 0.95782, 0.9858, 1.03989, 0.96924, 0.96924, 0.96924, 0.96924, 0.96924, 1.17308, 0.96924, 0.95402, 0.95402, 0.95402, 0.95402, 0.83089, 0.86237, 0.88409, 0.97454, 0.97454, 0.97454, 0.97454, 0.97454, 0.97454, 0.92916, 0.87207, 0.87533, 0.87533, 0.87533, 0.87533, 0.93146, 0.93146, 0.93146, 0.93146, 0.93854, 1.01054, 0.96225, 0.96225, 0.96225, 0.96225, 0.96225, 1.24822, 0.8761, 1.00351, 1.00351, 1.00351, 1.00351, 0.96777, 0.97454, 0.96777, 0.94729, 0.97454, 0.94729, 0.97454, 0.94729, 0.97454, 0.88506, 0.87207, 0.88506, 0.87207, 0.88506, 0.87207, 0.88506, 0.87207, 0.9858, 0.95391, 0.9858, 0.97454, 0.74817, 0.87533, 0.74817, 0.87533, 0.74817, 0.87533, 0.74817, 0.87533, 0.74817, 0.87533, 0.88449, 0.97454, 0.88449, 0.97454, 0.88449, 0.97454, 1, 1, 0.98039, 1.00176, 0.98039, 1.00176, 0.95782, 0.93146, 0.95782, 0.93146, 0.95782, 0.93146, 0.95782, 1.16484, 0.95782, 0.93146, 0.84421, 1.12761, 0.69238, 1.08132, 1, 1, 0.98047, 0.83231, 1.16484, 1, 1, 0.84723, 1.04861, 0.84723, 0.78755, 0.83231, 1.23736, 1.03989, 1.01054, 1, 1, 1.03989, 1.01054, 0.9857, 1.03849, 1.01054, 0.96924, 0.96225, 0.96924, 0.96225, 0.96924, 0.96225, 0.92383, 0.90171, 0.80595, 1.06598, 1, 1, 0.80595, 1.06598, 0.74524, 0.79004, 0.74524, 0.79004, 0.74524, 0.79004, 0.74524, 0.79004, 1, 1, 0.86091, 1.02759, 0.85771, 1.16344, 0.95402, 1.00351, 0.95402, 1.00351, 0.95402, 1.00351, 0.95402, 1.00351, 0.95402, 1.00351, 0.95402, 1.00351, 0.98448, 0.9973, 0.83089, 0.96777, 0.83089, 0.93285, 0.9043, 0.93285, 0.9043, 0.93285, 0.9043, 1.31868, 0.96927, 0.94729, 0.97454, 0.85498, 0.92916, 0.96924, 0.8761, 1, 1, 0.86091, 1.16344, 1.04839, 1.04839, 1.04839, 1.04839, 1.04839, 1.04839, 1.04839, 1.04839, 1.04839, 0.81965, 0.81965, 0.94729, 0.78032, 0.71022, 0.90883, 0.84171, 0.99877, 0.77596, 1.05734, 1.2, 0.94729, 0.85944, 0.82791, 0.9607, 0.74817, 0.93285, 0.98039, 0.96924, 0.95782, 0.89898, 0.98316, 0.98183, 1.03989, 0.78614, 0.96924, 0.97642, 0.86237, 0.86075, 0.86091, 0.83089, 0.90082, 0.8858, 0.97296, 1.01284, 0.95782, 0.83089, 1.0976, 1.04, 1.03342, 1.2, 1.0675, 1.0976, 0.98205, 1.03809, 1.05097, 1.04, 0.95364, 1.03342, 1.05401, 1.2, 1.02148, 1.0119, 1.04724, 1.0127, 1.02732, 0.96225, 0.8965, 0.97783, 0.93574, 0.94818, 1.30679, 1.0675, 1.11826, 0.99821, 1.0557, 1.0326, 1.2, 1.0675, 0.96225, 1.0675, 1.0326, 0.74817, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.03754, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.87533, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.98705, 1, 1, 1, 1, 1, 1, 0.98448, 0.9973, 0.98448, 0.9973, 0.98448, 0.9973, 0.83089, 0.96777, 1, 1.20088, 0.89903, 1, 1, 0.75155, 0.94945, 0.94945, 0.94945, 0.94945, 1.12317, 1.12317, 1.12317, 0.67603, 0.67603, 1.15621, 0.73584, 1.21191, 1.22135, 1.06483, 0.94868, 0.94868, 0.95996, 1.24633, 1, 1.07497, 0.87709, 0.96927, 1.01473, 0.96927, 1, 1, 1, 0.77295, 1, 1, 1.09836, 1.09836, 1.09836, 1.01522, 0.86321, 0.94434, 0.8649, 0.94434, 0.86182, 1, 1, 1.083, 1, 0.91578, 0.86438, 1.17308, 1.18416, 1.14589, 0.69825, 0.97622, 1.96791, 1.24822, 1.24822, 1.17308, 1.24822, 1.24822, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.42603, 1, 0.99862, 0.99862, 1, 0.87025, 0.87025, 0.87025, 0.87025, 1.17984, 1.42603, 1, 1.42603, 1.42603, 0.99862, 1, 1, 1, 1, 1, 1.2886, 1.04315, 1.15296, 1.34163, 1, 1, 1, 1.10742, 1.10742, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];\nconst SegoeuiItalicMetrics = {\n  lineHeight: 1.33008,\n  lineGap: 0\n};\nconst SegoeuiRegularFactors = [1.76738, 1, 1, 0.98594, 1.02285, 1.10454, 1.06234, 0.96927, 0.92037, 1.19985, 1.2046, 0.90616, 0.90616, 1.07152, 1.1714, 0.78032, 1.20088, 0.78032, 1.40246, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.78032, 0.78032, 1.1714, 1.1714, 1.1714, 0.80597, 0.94084, 0.96706, 0.85944, 0.85734, 0.97093, 0.75842, 0.79936, 0.88198, 0.9831, 0.95782, 0.71387, 0.86969, 0.84636, 1.07796, 1.03584, 0.96924, 0.83968, 0.96924, 0.82826, 0.79649, 0.85771, 0.95132, 0.93119, 0.98965, 0.88433, 0.8287, 0.93365, 1.08612, 1.3638, 1.08612, 1.45786, 0.74627, 0.80499, 0.91484, 1.05707, 0.92383, 1.05882, 0.9403, 1.12654, 1.05882, 1.01756, 1.09011, 1.09011, 0.99414, 1.09011, 1.034, 1.01756, 1.05356, 1.05707, 1.05882, 1.04399, 0.84863, 1.21968, 1.01756, 0.95801, 1.00068, 0.91797, 0.96777, 0.9043, 0.90351, 0.92105, 0.90351, 1.1714, 0.85337, 0.96927, 0.96927, 0.99912, 0.96927, 0.92105, 0.80597, 1.2434, 1.20808, 1.05937, 0.90957, 1.1714, 1.20808, 0.75155, 0.94261, 1.24644, 1.09971, 1.09971, 0.84751, 1, 0.85273, 0.78032, 0.61584, 1.05425, 1.17914, 0.90957, 1.08665, 1.11593, 1.14169, 0.73381, 0.96706, 0.96706, 0.96706, 0.96706, 0.96706, 0.96706, 0.86035, 0.85734, 0.75842, 0.75842, 0.75842, 0.75842, 0.95782, 0.95782, 0.95782, 0.95782, 0.97093, 1.03584, 0.96924, 0.96924, 0.96924, 0.96924, 0.96924, 1.1714, 0.96924, 0.95132, 0.95132, 0.95132, 0.95132, 0.8287, 0.83968, 0.89049, 0.91484, 0.91484, 0.91484, 0.91484, 0.91484, 0.91484, 0.93575, 0.92383, 0.9403, 0.9403, 0.9403, 0.9403, 0.8717, 0.8717, 0.8717, 0.8717, 1.00527, 1.01756, 1.05356, 1.05356, 1.05356, 1.05356, 1.05356, 1.24644, 0.95923, 1.01756, 1.01756, 1.01756, 1.01756, 0.96777, 1.05707, 0.96777, 0.96706, 0.91484, 0.96706, 0.91484, 0.96706, 0.91484, 0.85734, 0.92383, 0.85734, 0.92383, 0.85734, 0.92383, 0.85734, 0.92383, 0.97093, 1.0969, 0.97093, 1.05882, 0.75842, 0.9403, 0.75842, 0.9403, 0.75842, 0.9403, 0.75842, 0.9403, 0.75842, 0.9403, 0.88198, 1.05882, 0.88198, 1.05882, 0.88198, 1.05882, 1, 1, 0.9831, 1.01756, 0.9831, 1.01756, 0.95782, 0.8717, 0.95782, 0.8717, 0.95782, 0.8717, 0.95782, 1.09011, 0.95782, 0.8717, 0.84784, 1.11551, 0.71387, 1.09011, 1, 1, 0.99414, 0.84636, 1.09011, 1, 1, 0.84636, 1.0536, 0.84636, 0.94298, 0.84636, 1.23297, 1.03584, 1.01756, 1, 1, 1.03584, 1.01756, 1.00323, 1.03444, 1.01756, 0.96924, 1.05356, 0.96924, 1.05356, 0.96924, 1.05356, 0.93066, 0.98293, 0.82826, 1.04399, 1, 1, 0.82826, 1.04399, 0.79649, 0.84863, 0.79649, 0.84863, 0.79649, 0.84863, 0.79649, 0.84863, 1, 1, 0.85771, 1.17318, 0.85771, 1.21968, 0.95132, 1.01756, 0.95132, 1.01756, 0.95132, 1.01756, 0.95132, 1.01756, 0.95132, 1.01756, 0.95132, 1.01756, 0.98965, 1.00068, 0.8287, 0.96777, 0.8287, 0.93365, 0.9043, 0.93365, 0.9043, 0.93365, 0.9043, 1.08571, 0.96927, 0.96706, 0.91484, 0.86035, 0.93575, 0.96924, 0.95923, 1, 1, 0.85771, 1.21968, 1.11437, 1.11437, 0.93109, 0.91202, 0.60411, 0.84164, 0.55572, 1.01173, 0.97361, 0.81818, 0.81818, 0.96635, 0.78032, 0.72727, 0.92366, 0.98601, 1.03405, 0.77968, 1.09799, 1.2, 0.96706, 0.85944, 0.85638, 0.96491, 0.75842, 0.93365, 0.9831, 0.96924, 0.95782, 0.86969, 0.94152, 1.07796, 1.03584, 0.78437, 0.96924, 0.98715, 0.83968, 0.83491, 0.85771, 0.8287, 0.94492, 0.88433, 0.9287, 1.0098, 0.95782, 0.8287, 1.0625, 0.98248, 1.03424, 1.2, 1.01071, 1.0625, 0.95246, 1.03809, 1.04912, 0.98248, 1.00221, 1.03424, 1.05443, 1.2, 1.04785, 0.99609, 1.00169, 1.05176, 0.99346, 1.05356, 0.9087, 1.03004, 0.95542, 0.93117, 1.23362, 1.01071, 1.07831, 1.02512, 1.05205, 1.03502, 1.2, 1.01071, 1.05356, 1.01071, 1.03502, 0.75842, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.03719, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9403, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.04021, 1, 1, 1, 1, 1, 1, 0.98965, 1.00068, 0.98965, 1.00068, 0.98965, 1.00068, 0.8287, 0.96777, 1, 1.20088, 0.89903, 1, 1, 0.75155, 1.03077, 1.03077, 1.03077, 1.03077, 1.13196, 1.13196, 1.13196, 0.67428, 0.67428, 1.16039, 0.73291, 1.20996, 1.22135, 1.06483, 0.94868, 0.94868, 0.95996, 1.24633, 1, 1.07497, 0.87796, 0.96927, 1.01518, 0.96927, 1, 1, 1, 0.77295, 1, 1, 1.10539, 1.10539, 1.11358, 1.06967, 0.86279, 0.94434, 0.86279, 0.94434, 0.86182, 1, 1, 1.083, 1, 0.91578, 0.86507, 1.1714, 1.18416, 1.14589, 0.69825, 0.97622, 1.9697, 1.24822, 1.24822, 1.17238, 1.24822, 1.24822, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.42603, 1, 0.99862, 0.99862, 1, 0.87025, 0.87025, 0.87025, 0.87025, 1.18083, 1.42603, 1, 1.42603, 1.42603, 0.99862, 1, 1, 1, 1, 1, 1.2886, 1.04315, 1.15296, 1.34163, 1, 1, 1, 1.10938, 1.10938, 1, 1, 1, 1.05425, 1.09971, 1.09971, 1.09971, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];\nconst SegoeuiRegularMetrics = {\n  lineHeight: 1.33008,\n  lineGap: 0\n};\n\n;// ./src/core/xfa_fonts.js\n\n\n\n\n\n\n\n\nconst getXFAFontMap = getLookupTableFactory(function (t) {\n  t[\"MyriadPro-Regular\"] = t[\"PdfJS-Fallback-Regular\"] = {\n    name: \"LiberationSans-Regular\",\n    factors: MyriadProRegularFactors,\n    baseWidths: LiberationSansRegularWidths,\n    baseMapping: LiberationSansRegularMapping,\n    metrics: MyriadProRegularMetrics\n  };\n  t[\"MyriadPro-Bold\"] = t[\"PdfJS-Fallback-Bold\"] = {\n    name: \"LiberationSans-Bold\",\n    factors: MyriadProBoldFactors,\n    baseWidths: LiberationSansBoldWidths,\n    baseMapping: LiberationSansBoldMapping,\n    metrics: MyriadProBoldMetrics\n  };\n  t[\"MyriadPro-It\"] = t[\"MyriadPro-Italic\"] = t[\"PdfJS-Fallback-Italic\"] = {\n    name: \"LiberationSans-Italic\",\n    factors: MyriadProItalicFactors,\n    baseWidths: LiberationSansItalicWidths,\n    baseMapping: LiberationSansItalicMapping,\n    metrics: MyriadProItalicMetrics\n  };\n  t[\"MyriadPro-BoldIt\"] = t[\"MyriadPro-BoldItalic\"] = t[\"PdfJS-Fallback-BoldItalic\"] = {\n    name: \"LiberationSans-BoldItalic\",\n    factors: MyriadProBoldItalicFactors,\n    baseWidths: LiberationSansBoldItalicWidths,\n    baseMapping: LiberationSansBoldItalicMapping,\n    metrics: MyriadProBoldItalicMetrics\n  };\n  t.ArialMT = t.Arial = t[\"Arial-Regular\"] = {\n    name: \"LiberationSans-Regular\",\n    baseWidths: LiberationSansRegularWidths,\n    baseMapping: LiberationSansRegularMapping\n  };\n  t[\"Arial-BoldMT\"] = t[\"Arial-Bold\"] = {\n    name: \"LiberationSans-Bold\",\n    baseWidths: LiberationSansBoldWidths,\n    baseMapping: LiberationSansBoldMapping\n  };\n  t[\"Arial-ItalicMT\"] = t[\"Arial-Italic\"] = {\n    name: \"LiberationSans-Italic\",\n    baseWidths: LiberationSansItalicWidths,\n    baseMapping: LiberationSansItalicMapping\n  };\n  t[\"Arial-BoldItalicMT\"] = t[\"Arial-BoldItalic\"] = {\n    name: \"LiberationSans-BoldItalic\",\n    baseWidths: LiberationSansBoldItalicWidths,\n    baseMapping: LiberationSansBoldItalicMapping\n  };\n  t[\"Calibri-Regular\"] = {\n    name: \"LiberationSans-Regular\",\n    factors: CalibriRegularFactors,\n    baseWidths: LiberationSansRegularWidths,\n    baseMapping: LiberationSansRegularMapping,\n    metrics: CalibriRegularMetrics\n  };\n  t[\"Calibri-Bold\"] = {\n    name: \"LiberationSans-Bold\",\n    factors: CalibriBoldFactors,\n    baseWidths: LiberationSansBoldWidths,\n    baseMapping: LiberationSansBoldMapping,\n    metrics: CalibriBoldMetrics\n  };\n  t[\"Calibri-Italic\"] = {\n    name: \"LiberationSans-Italic\",\n    factors: CalibriItalicFactors,\n    baseWidths: LiberationSansItalicWidths,\n    baseMapping: LiberationSansItalicMapping,\n    metrics: CalibriItalicMetrics\n  };\n  t[\"Calibri-BoldItalic\"] = {\n    name: \"LiberationSans-BoldItalic\",\n    factors: CalibriBoldItalicFactors,\n    baseWidths: LiberationSansBoldItalicWidths,\n    baseMapping: LiberationSansBoldItalicMapping,\n    metrics: CalibriBoldItalicMetrics\n  };\n  t[\"Segoeui-Regular\"] = {\n    name: \"LiberationSans-Regular\",\n    factors: SegoeuiRegularFactors,\n    baseWidths: LiberationSansRegularWidths,\n    baseMapping: LiberationSansRegularMapping,\n    metrics: SegoeuiRegularMetrics\n  };\n  t[\"Segoeui-Bold\"] = {\n    name: \"LiberationSans-Bold\",\n    factors: SegoeuiBoldFactors,\n    baseWidths: LiberationSansBoldWidths,\n    baseMapping: LiberationSansBoldMapping,\n    metrics: SegoeuiBoldMetrics\n  };\n  t[\"Segoeui-Italic\"] = {\n    name: \"LiberationSans-Italic\",\n    factors: SegoeuiItalicFactors,\n    baseWidths: LiberationSansItalicWidths,\n    baseMapping: LiberationSansItalicMapping,\n    metrics: SegoeuiItalicMetrics\n  };\n  t[\"Segoeui-BoldItalic\"] = {\n    name: \"LiberationSans-BoldItalic\",\n    factors: SegoeuiBoldItalicFactors,\n    baseWidths: LiberationSansBoldItalicWidths,\n    baseMapping: LiberationSansBoldItalicMapping,\n    metrics: SegoeuiBoldItalicMetrics\n  };\n  t[\"Helvetica-Regular\"] = t.Helvetica = {\n    name: \"LiberationSans-Regular\",\n    factors: HelveticaRegularFactors,\n    baseWidths: LiberationSansRegularWidths,\n    baseMapping: LiberationSansRegularMapping,\n    metrics: HelveticaRegularMetrics\n  };\n  t[\"Helvetica-Bold\"] = {\n    name: \"LiberationSans-Bold\",\n    factors: HelveticaBoldFactors,\n    baseWidths: LiberationSansBoldWidths,\n    baseMapping: LiberationSansBoldMapping,\n    metrics: HelveticaBoldMetrics\n  };\n  t[\"Helvetica-Italic\"] = {\n    name: \"LiberationSans-Italic\",\n    factors: HelveticaItalicFactors,\n    baseWidths: LiberationSansItalicWidths,\n    baseMapping: LiberationSansItalicMapping,\n    metrics: HelveticaItalicMetrics\n  };\n  t[\"Helvetica-BoldItalic\"] = {\n    name: \"LiberationSans-BoldItalic\",\n    factors: HelveticaBoldItalicFactors,\n    baseWidths: LiberationSansBoldItalicWidths,\n    baseMapping: LiberationSansBoldItalicMapping,\n    metrics: HelveticaBoldItalicMetrics\n  };\n});\nfunction getXfaFontName(name) {\n  const fontName = normalizeFontName(name);\n  const fontMap = getXFAFontMap();\n  return fontMap[fontName];\n}\nfunction getXfaFontWidths(name) {\n  const info = getXfaFontName(name);\n  if (!info) {\n    return null;\n  }\n  const {\n    baseWidths,\n    baseMapping,\n    factors\n  } = info;\n  const rescaledBaseWidths = !factors ? baseWidths : baseWidths.map((w, i) => w * factors[i]);\n  let currentCode = -2;\n  let currentArray;\n  const newWidths = [];\n  for (const [unicode, glyphIndex] of baseMapping.map((charUnicode, index) => [charUnicode, index]).sort(([unicode1], [unicode2]) => unicode1 - unicode2)) {\n    if (unicode === -1) {\n      continue;\n    }\n    if (unicode === currentCode + 1) {\n      currentArray.push(rescaledBaseWidths[glyphIndex]);\n      currentCode += 1;\n    } else {\n      currentCode = unicode;\n      currentArray = [rescaledBaseWidths[glyphIndex]];\n      newWidths.push(unicode, currentArray);\n    }\n  }\n  return newWidths;\n}\nfunction getXfaFontDict(name) {\n  const widths = getXfaFontWidths(name);\n  const dict = new Dict(null);\n  dict.set(\"BaseFont\", Name.get(name));\n  dict.set(\"Type\", Name.get(\"Font\"));\n  dict.set(\"Subtype\", Name.get(\"CIDFontType2\"));\n  dict.set(\"Encoding\", Name.get(\"Identity-H\"));\n  dict.set(\"CIDToGIDMap\", Name.get(\"Identity\"));\n  dict.set(\"W\", widths);\n  dict.set(\"FirstChar\", widths[0]);\n  dict.set(\"LastChar\", widths.at(-2) + widths.at(-1).length - 1);\n  const descriptor = new Dict(null);\n  dict.set(\"FontDescriptor\", descriptor);\n  const systemInfo = new Dict(null);\n  systemInfo.set(\"Ordering\", \"Identity\");\n  systemInfo.set(\"Registry\", \"Adobe\");\n  systemInfo.set(\"Supplement\", 0);\n  dict.set(\"CIDSystemInfo\", systemInfo);\n  return dict;\n}\n\n;// ./src/core/ps_parser.js\n\n\n\nclass PostScriptParser {\n  constructor(lexer) {\n    this.lexer = lexer;\n    this.operators = [];\n    this.token = null;\n    this.prev = null;\n  }\n  nextToken() {\n    this.prev = this.token;\n    this.token = this.lexer.getToken();\n  }\n  accept(type) {\n    if (this.token.type === type) {\n      this.nextToken();\n      return true;\n    }\n    return false;\n  }\n  expect(type) {\n    if (this.accept(type)) {\n      return true;\n    }\n    throw new FormatError(`Unexpected symbol: found ${this.token.type} expected ${type}.`);\n  }\n  parse() {\n    this.nextToken();\n    this.expect(PostScriptTokenTypes.LBRACE);\n    this.parseBlock();\n    this.expect(PostScriptTokenTypes.RBRACE);\n    return this.operators;\n  }\n  parseBlock() {\n    while (true) {\n      if (this.accept(PostScriptTokenTypes.NUMBER)) {\n        this.operators.push(this.prev.value);\n      } else if (this.accept(PostScriptTokenTypes.OPERATOR)) {\n        this.operators.push(this.prev.value);\n      } else if (this.accept(PostScriptTokenTypes.LBRACE)) {\n        this.parseCondition();\n      } else {\n        return;\n      }\n    }\n  }\n  parseCondition() {\n    const conditionLocation = this.operators.length;\n    this.operators.push(null, null);\n    this.parseBlock();\n    this.expect(PostScriptTokenTypes.RBRACE);\n    if (this.accept(PostScriptTokenTypes.IF)) {\n      this.operators[conditionLocation] = this.operators.length;\n      this.operators[conditionLocation + 1] = \"jz\";\n    } else if (this.accept(PostScriptTokenTypes.LBRACE)) {\n      const jumpLocation = this.operators.length;\n      this.operators.push(null, null);\n      const endOfTrue = this.operators.length;\n      this.parseBlock();\n      this.expect(PostScriptTokenTypes.RBRACE);\n      this.expect(PostScriptTokenTypes.IFELSE);\n      this.operators[jumpLocation] = this.operators.length;\n      this.operators[jumpLocation + 1] = \"j\";\n      this.operators[conditionLocation] = endOfTrue;\n      this.operators[conditionLocation + 1] = \"jz\";\n    } else {\n      throw new FormatError(\"PS Function: error parsing conditional.\");\n    }\n  }\n}\nconst PostScriptTokenTypes = {\n  LBRACE: 0,\n  RBRACE: 1,\n  NUMBER: 2,\n  OPERATOR: 3,\n  IF: 4,\n  IFELSE: 5\n};\nclass PostScriptToken {\n  static get opCache() {\n    return shadow(this, \"opCache\", Object.create(null));\n  }\n  constructor(type, value) {\n    this.type = type;\n    this.value = value;\n  }\n  static getOperator(op) {\n    return PostScriptToken.opCache[op] ||= new PostScriptToken(PostScriptTokenTypes.OPERATOR, op);\n  }\n  static get LBRACE() {\n    return shadow(this, \"LBRACE\", new PostScriptToken(PostScriptTokenTypes.LBRACE, \"{\"));\n  }\n  static get RBRACE() {\n    return shadow(this, \"RBRACE\", new PostScriptToken(PostScriptTokenTypes.RBRACE, \"}\"));\n  }\n  static get IF() {\n    return shadow(this, \"IF\", new PostScriptToken(PostScriptTokenTypes.IF, \"IF\"));\n  }\n  static get IFELSE() {\n    return shadow(this, \"IFELSE\", new PostScriptToken(PostScriptTokenTypes.IFELSE, \"IFELSE\"));\n  }\n}\nclass PostScriptLexer {\n  constructor(stream) {\n    this.stream = stream;\n    this.nextChar();\n    this.strBuf = [];\n  }\n  nextChar() {\n    return this.currentChar = this.stream.getByte();\n  }\n  getToken() {\n    let comment = false;\n    let ch = this.currentChar;\n    while (true) {\n      if (ch < 0) {\n        return EOF;\n      }\n      if (comment) {\n        if (ch === 0x0a || ch === 0x0d) {\n          comment = false;\n        }\n      } else if (ch === 0x25) {\n        comment = true;\n      } else if (!isWhiteSpace(ch)) {\n        break;\n      }\n      ch = this.nextChar();\n    }\n    switch (ch | 0) {\n      case 0x30:\n      case 0x31:\n      case 0x32:\n      case 0x33:\n      case 0x34:\n      case 0x35:\n      case 0x36:\n      case 0x37:\n      case 0x38:\n      case 0x39:\n      case 0x2b:\n      case 0x2d:\n      case 0x2e:\n        return new PostScriptToken(PostScriptTokenTypes.NUMBER, this.getNumber());\n      case 0x7b:\n        this.nextChar();\n        return PostScriptToken.LBRACE;\n      case 0x7d:\n        this.nextChar();\n        return PostScriptToken.RBRACE;\n    }\n    const strBuf = this.strBuf;\n    strBuf.length = 0;\n    strBuf[0] = String.fromCharCode(ch);\n    while ((ch = this.nextChar()) >= 0 && (ch >= 0x41 && ch <= 0x5a || ch >= 0x61 && ch <= 0x7a)) {\n      strBuf.push(String.fromCharCode(ch));\n    }\n    const str = strBuf.join(\"\");\n    switch (str.toLowerCase()) {\n      case \"if\":\n        return PostScriptToken.IF;\n      case \"ifelse\":\n        return PostScriptToken.IFELSE;\n      default:\n        return PostScriptToken.getOperator(str);\n    }\n  }\n  getNumber() {\n    let ch = this.currentChar;\n    const strBuf = this.strBuf;\n    strBuf.length = 0;\n    strBuf[0] = String.fromCharCode(ch);\n    while ((ch = this.nextChar()) >= 0) {\n      if (ch >= 0x30 && ch <= 0x39 || ch === 0x2d || ch === 0x2e) {\n        strBuf.push(String.fromCharCode(ch));\n      } else {\n        break;\n      }\n    }\n    const value = parseFloat(strBuf.join(\"\"));\n    if (isNaN(value)) {\n      throw new FormatError(`Invalid floating point number: ${value}`);\n    }\n    return value;\n  }\n}\n\n;// ./src/core/image_utils.js\n\n\nclass BaseLocalCache {\n  constructor(options) {\n    if (this.constructor === BaseLocalCache) {\n      unreachable(\"Cannot initialize BaseLocalCache.\");\n    }\n    this._onlyRefs = options?.onlyRefs === true;\n    if (!this._onlyRefs) {\n      this._nameRefMap = new Map();\n      this._imageMap = new Map();\n    }\n    this._imageCache = new RefSetCache();\n  }\n  getByName(name) {\n    if (this._onlyRefs) {\n      unreachable(\"Should not call `getByName` method.\");\n    }\n    const ref = this._nameRefMap.get(name);\n    if (ref) {\n      return this.getByRef(ref);\n    }\n    return this._imageMap.get(name) || null;\n  }\n  getByRef(ref) {\n    return this._imageCache.get(ref) || null;\n  }\n  set(name, ref, data) {\n    unreachable(\"Abstract method `set` called.\");\n  }\n}\nclass LocalImageCache extends BaseLocalCache {\n  set(name, ref = null, data) {\n    if (typeof name !== \"string\") {\n      throw new Error('LocalImageCache.set - expected \"name\" argument.');\n    }\n    if (ref) {\n      if (this._imageCache.has(ref)) {\n        return;\n      }\n      this._nameRefMap.set(name, ref);\n      this._imageCache.put(ref, data);\n      return;\n    }\n    if (this._imageMap.has(name)) {\n      return;\n    }\n    this._imageMap.set(name, data);\n  }\n}\nclass LocalColorSpaceCache extends BaseLocalCache {\n  set(name = null, ref = null, data) {\n    if (typeof name !== \"string\" && !ref) {\n      throw new Error('LocalColorSpaceCache.set - expected \"name\" and/or \"ref\" argument.');\n    }\n    if (ref) {\n      if (this._imageCache.has(ref)) {\n        return;\n      }\n      if (name !== null) {\n        this._nameRefMap.set(name, ref);\n      }\n      this._imageCache.put(ref, data);\n      return;\n    }\n    if (this._imageMap.has(name)) {\n      return;\n    }\n    this._imageMap.set(name, data);\n  }\n}\nclass LocalFunctionCache extends BaseLocalCache {\n  constructor(options) {\n    super({\n      onlyRefs: true\n    });\n  }\n  set(name = null, ref, data) {\n    if (!ref) {\n      throw new Error('LocalFunctionCache.set - expected \"ref\" argument.');\n    }\n    if (this._imageCache.has(ref)) {\n      return;\n    }\n    this._imageCache.put(ref, data);\n  }\n}\nclass LocalGStateCache extends BaseLocalCache {\n  set(name, ref = null, data) {\n    if (typeof name !== \"string\") {\n      throw new Error('LocalGStateCache.set - expected \"name\" argument.');\n    }\n    if (ref) {\n      if (this._imageCache.has(ref)) {\n        return;\n      }\n      this._nameRefMap.set(name, ref);\n      this._imageCache.put(ref, data);\n      return;\n    }\n    if (this._imageMap.has(name)) {\n      return;\n    }\n    this._imageMap.set(name, data);\n  }\n}\nclass LocalTilingPatternCache extends BaseLocalCache {\n  constructor(options) {\n    super({\n      onlyRefs: true\n    });\n  }\n  set(name = null, ref, data) {\n    if (!ref) {\n      throw new Error('LocalTilingPatternCache.set - expected \"ref\" argument.');\n    }\n    if (this._imageCache.has(ref)) {\n      return;\n    }\n    this._imageCache.put(ref, data);\n  }\n}\nclass RegionalImageCache extends BaseLocalCache {\n  constructor(options) {\n    super({\n      onlyRefs: true\n    });\n  }\n  set(name = null, ref, data) {\n    if (!ref) {\n      throw new Error('RegionalImageCache.set - expected \"ref\" argument.');\n    }\n    if (this._imageCache.has(ref)) {\n      return;\n    }\n    this._imageCache.put(ref, data);\n  }\n}\nclass GlobalImageCache {\n  static NUM_PAGES_THRESHOLD = 2;\n  static MIN_IMAGES_TO_CACHE = 10;\n  static MAX_BYTE_SIZE = 5 * MAX_IMAGE_SIZE_TO_CACHE;\n  constructor() {\n    this._refCache = new RefSetCache();\n    this._imageCache = new RefSetCache();\n  }\n  get _byteSize() {\n    let byteSize = 0;\n    for (const imageData of this._imageCache) {\n      byteSize += imageData.byteSize;\n    }\n    return byteSize;\n  }\n  get _cacheLimitReached() {\n    if (this._imageCache.size < GlobalImageCache.MIN_IMAGES_TO_CACHE) {\n      return false;\n    }\n    if (this._byteSize < GlobalImageCache.MAX_BYTE_SIZE) {\n      return false;\n    }\n    return true;\n  }\n  shouldCache(ref, pageIndex) {\n    let pageIndexSet = this._refCache.get(ref);\n    if (!pageIndexSet) {\n      pageIndexSet = new Set();\n      this._refCache.put(ref, pageIndexSet);\n    }\n    pageIndexSet.add(pageIndex);\n    if (pageIndexSet.size < GlobalImageCache.NUM_PAGES_THRESHOLD) {\n      return false;\n    }\n    if (!this._imageCache.has(ref) && this._cacheLimitReached) {\n      return false;\n    }\n    return true;\n  }\n  addByteSize(ref, byteSize) {\n    const imageData = this._imageCache.get(ref);\n    if (!imageData) {\n      return;\n    }\n    if (imageData.byteSize) {\n      return;\n    }\n    imageData.byteSize = byteSize;\n  }\n  getData(ref, pageIndex) {\n    const pageIndexSet = this._refCache.get(ref);\n    if (!pageIndexSet) {\n      return null;\n    }\n    if (pageIndexSet.size < GlobalImageCache.NUM_PAGES_THRESHOLD) {\n      return null;\n    }\n    const imageData = this._imageCache.get(ref);\n    if (!imageData) {\n      return null;\n    }\n    pageIndexSet.add(pageIndex);\n    return imageData;\n  }\n  setData(ref, data) {\n    if (!this._refCache.has(ref)) {\n      throw new Error('GlobalImageCache.setData - expected \"shouldCache\" to have been called.');\n    }\n    if (this._imageCache.has(ref)) {\n      return;\n    }\n    if (this._cacheLimitReached) {\n      warn(\"GlobalImageCache.setData - cache limit reached.\");\n      return;\n    }\n    this._imageCache.put(ref, data);\n  }\n  clear(onlyData = false) {\n    if (!onlyData) {\n      this._refCache.clear();\n    }\n    this._imageCache.clear();\n  }\n}\n\n;// ./src/core/function.js\n\n\n\n\n\nclass PDFFunctionFactory {\n  constructor({\n    xref,\n    isEvalSupported = true\n  }) {\n    this.xref = xref;\n    this.isEvalSupported = isEvalSupported !== false;\n  }\n  create(fn) {\n    const cachedFunction = this.getCached(fn);\n    if (cachedFunction) {\n      return cachedFunction;\n    }\n    const parsedFunction = PDFFunction.parse({\n      xref: this.xref,\n      isEvalSupported: this.isEvalSupported,\n      fn: fn instanceof Ref ? this.xref.fetch(fn) : fn\n    });\n    this._cache(fn, parsedFunction);\n    return parsedFunction;\n  }\n  createFromArray(fnObj) {\n    const cachedFunction = this.getCached(fnObj);\n    if (cachedFunction) {\n      return cachedFunction;\n    }\n    const parsedFunction = PDFFunction.parseArray({\n      xref: this.xref,\n      isEvalSupported: this.isEvalSupported,\n      fnObj: fnObj instanceof Ref ? this.xref.fetch(fnObj) : fnObj\n    });\n    this._cache(fnObj, parsedFunction);\n    return parsedFunction;\n  }\n  getCached(cacheKey) {\n    let fnRef;\n    if (cacheKey instanceof Ref) {\n      fnRef = cacheKey;\n    } else if (cacheKey instanceof Dict) {\n      fnRef = cacheKey.objId;\n    } else if (cacheKey instanceof BaseStream) {\n      fnRef = cacheKey.dict?.objId;\n    }\n    if (fnRef) {\n      const localFunction = this._localFunctionCache.getByRef(fnRef);\n      if (localFunction) {\n        return localFunction;\n      }\n    }\n    return null;\n  }\n  _cache(cacheKey, parsedFunction) {\n    if (!parsedFunction) {\n      throw new Error('PDFFunctionFactory._cache - expected \"parsedFunction\" argument.');\n    }\n    let fnRef;\n    if (cacheKey instanceof Ref) {\n      fnRef = cacheKey;\n    } else if (cacheKey instanceof Dict) {\n      fnRef = cacheKey.objId;\n    } else if (cacheKey instanceof BaseStream) {\n      fnRef = cacheKey.dict?.objId;\n    }\n    if (fnRef) {\n      this._localFunctionCache.set(null, fnRef, parsedFunction);\n    }\n  }\n  get _localFunctionCache() {\n    return shadow(this, \"_localFunctionCache\", new LocalFunctionCache());\n  }\n}\nfunction toNumberArray(arr) {\n  if (!Array.isArray(arr)) {\n    return null;\n  }\n  const length = arr.length;\n  for (let i = 0; i < length; i++) {\n    if (typeof arr[i] !== \"number\") {\n      const result = new Array(length);\n      for (let j = 0; j < length; j++) {\n        result[j] = +arr[j];\n      }\n      return result;\n    }\n  }\n  return arr;\n}\nclass PDFFunction {\n  static getSampleArray(size, outputSize, bps, stream) {\n    let i, ii;\n    let length = 1;\n    for (i = 0, ii = size.length; i < ii; i++) {\n      length *= size[i];\n    }\n    length *= outputSize;\n    const array = new Array(length);\n    let codeSize = 0;\n    let codeBuf = 0;\n    const sampleMul = 1.0 / (2.0 ** bps - 1);\n    const strBytes = stream.getBytes((length * bps + 7) / 8);\n    let strIdx = 0;\n    for (i = 0; i < length; i++) {\n      while (codeSize < bps) {\n        codeBuf <<= 8;\n        codeBuf |= strBytes[strIdx++];\n        codeSize += 8;\n      }\n      codeSize -= bps;\n      array[i] = (codeBuf >> codeSize) * sampleMul;\n      codeBuf &= (1 << codeSize) - 1;\n    }\n    return array;\n  }\n  static parse({\n    xref,\n    isEvalSupported,\n    fn\n  }) {\n    const dict = fn.dict || fn;\n    const typeNum = dict.get(\"FunctionType\");\n    switch (typeNum) {\n      case 0:\n        return this.constructSampled({\n          xref,\n          isEvalSupported,\n          fn,\n          dict\n        });\n      case 1:\n        break;\n      case 2:\n        return this.constructInterpolated({\n          xref,\n          isEvalSupported,\n          dict\n        });\n      case 3:\n        return this.constructStiched({\n          xref,\n          isEvalSupported,\n          dict\n        });\n      case 4:\n        return this.constructPostScript({\n          xref,\n          isEvalSupported,\n          fn,\n          dict\n        });\n    }\n    throw new FormatError(\"Unknown type of function\");\n  }\n  static parseArray({\n    xref,\n    isEvalSupported,\n    fnObj\n  }) {\n    if (!Array.isArray(fnObj)) {\n      return this.parse({\n        xref,\n        isEvalSupported,\n        fn: fnObj\n      });\n    }\n    const fnArray = [];\n    for (const fn of fnObj) {\n      fnArray.push(this.parse({\n        xref,\n        isEvalSupported,\n        fn: xref.fetchIfRef(fn)\n      }));\n    }\n    return function (src, srcOffset, dest, destOffset) {\n      for (let i = 0, ii = fnArray.length; i < ii; i++) {\n        fnArray[i](src, srcOffset, dest, destOffset + i);\n      }\n    };\n  }\n  static constructSampled({\n    xref,\n    isEvalSupported,\n    fn,\n    dict\n  }) {\n    function toMultiArray(arr) {\n      const inputLength = arr.length;\n      const out = [];\n      let index = 0;\n      for (let i = 0; i < inputLength; i += 2) {\n        out[index++] = [arr[i], arr[i + 1]];\n      }\n      return out;\n    }\n    function interpolate(x, xmin, xmax, ymin, ymax) {\n      return ymin + (x - xmin) * ((ymax - ymin) / (xmax - xmin));\n    }\n    let domain = toNumberArray(dict.getArray(\"Domain\"));\n    let range = toNumberArray(dict.getArray(\"Range\"));\n    if (!domain || !range) {\n      throw new FormatError(\"No domain or range\");\n    }\n    const inputSize = domain.length / 2;\n    const outputSize = range.length / 2;\n    domain = toMultiArray(domain);\n    range = toMultiArray(range);\n    const size = toNumberArray(dict.getArray(\"Size\"));\n    const bps = dict.get(\"BitsPerSample\");\n    const order = dict.get(\"Order\") || 1;\n    if (order !== 1) {\n      info(\"No support for cubic spline interpolation: \" + order);\n    }\n    let encode = toNumberArray(dict.getArray(\"Encode\"));\n    if (!encode) {\n      encode = [];\n      for (let i = 0; i < inputSize; ++i) {\n        encode.push([0, size[i] - 1]);\n      }\n    } else {\n      encode = toMultiArray(encode);\n    }\n    let decode = toNumberArray(dict.getArray(\"Decode\"));\n    decode = !decode ? range : toMultiArray(decode);\n    const samples = this.getSampleArray(size, outputSize, bps, fn);\n    return function constructSampledFn(src, srcOffset, dest, destOffset) {\n      const cubeVertices = 1 << inputSize;\n      const cubeN = new Float64Array(cubeVertices);\n      const cubeVertex = new Uint32Array(cubeVertices);\n      let i, j;\n      for (j = 0; j < cubeVertices; j++) {\n        cubeN[j] = 1;\n      }\n      let k = outputSize,\n        pos = 1;\n      for (i = 0; i < inputSize; ++i) {\n        const domain_2i = domain[i][0];\n        const domain_2i_1 = domain[i][1];\n        const xi = Math.min(Math.max(src[srcOffset + i], domain_2i), domain_2i_1);\n        let e = interpolate(xi, domain_2i, domain_2i_1, encode[i][0], encode[i][1]);\n        const size_i = size[i];\n        e = Math.min(Math.max(e, 0), size_i - 1);\n        const e0 = e < size_i - 1 ? Math.floor(e) : e - 1;\n        const n0 = e0 + 1 - e;\n        const n1 = e - e0;\n        const offset0 = e0 * k;\n        const offset1 = offset0 + k;\n        for (j = 0; j < cubeVertices; j++) {\n          if (j & pos) {\n            cubeN[j] *= n1;\n            cubeVertex[j] += offset1;\n          } else {\n            cubeN[j] *= n0;\n            cubeVertex[j] += offset0;\n          }\n        }\n        k *= size_i;\n        pos <<= 1;\n      }\n      for (j = 0; j < outputSize; ++j) {\n        let rj = 0;\n        for (i = 0; i < cubeVertices; i++) {\n          rj += samples[cubeVertex[i] + j] * cubeN[i];\n        }\n        rj = interpolate(rj, 0, 1, decode[j][0], decode[j][1]);\n        dest[destOffset + j] = Math.min(Math.max(rj, range[j][0]), range[j][1]);\n      }\n    };\n  }\n  static constructInterpolated({\n    xref,\n    isEvalSupported,\n    dict\n  }) {\n    const c0 = toNumberArray(dict.getArray(\"C0\")) || [0];\n    const c1 = toNumberArray(dict.getArray(\"C1\")) || [1];\n    const n = dict.get(\"N\");\n    const diff = [];\n    for (let i = 0, ii = c0.length; i < ii; ++i) {\n      diff.push(c1[i] - c0[i]);\n    }\n    const length = diff.length;\n    return function constructInterpolatedFn(src, srcOffset, dest, destOffset) {\n      const x = n === 1 ? src[srcOffset] : src[srcOffset] ** n;\n      for (let j = 0; j < length; ++j) {\n        dest[destOffset + j] = c0[j] + x * diff[j];\n      }\n    };\n  }\n  static constructStiched({\n    xref,\n    isEvalSupported,\n    dict\n  }) {\n    const domain = toNumberArray(dict.getArray(\"Domain\"));\n    if (!domain) {\n      throw new FormatError(\"No domain\");\n    }\n    const inputSize = domain.length / 2;\n    if (inputSize !== 1) {\n      throw new FormatError(\"Bad domain for stiched function\");\n    }\n    const fns = [];\n    for (const fn of dict.get(\"Functions\")) {\n      fns.push(this.parse({\n        xref,\n        isEvalSupported,\n        fn: xref.fetchIfRef(fn)\n      }));\n    }\n    const bounds = toNumberArray(dict.getArray(\"Bounds\"));\n    const encode = toNumberArray(dict.getArray(\"Encode\"));\n    const tmpBuf = new Float32Array(1);\n    return function constructStichedFn(src, srcOffset, dest, destOffset) {\n      const clip = function constructStichedFromIRClip(v, min, max) {\n        if (v > max) {\n          v = max;\n        } else if (v < min) {\n          v = min;\n        }\n        return v;\n      };\n      const v = clip(src[srcOffset], domain[0], domain[1]);\n      const length = bounds.length;\n      let i;\n      for (i = 0; i < length; ++i) {\n        if (v < bounds[i]) {\n          break;\n        }\n      }\n      let dmin = domain[0];\n      if (i > 0) {\n        dmin = bounds[i - 1];\n      }\n      let dmax = domain[1];\n      if (i < bounds.length) {\n        dmax = bounds[i];\n      }\n      const rmin = encode[2 * i];\n      const rmax = encode[2 * i + 1];\n      tmpBuf[0] = dmin === dmax ? rmin : rmin + (v - dmin) * (rmax - rmin) / (dmax - dmin);\n      fns[i](tmpBuf, 0, dest, destOffset);\n    };\n  }\n  static constructPostScript({\n    xref,\n    isEvalSupported,\n    fn,\n    dict\n  }) {\n    const domain = toNumberArray(dict.getArray(\"Domain\"));\n    const range = toNumberArray(dict.getArray(\"Range\"));\n    if (!domain) {\n      throw new FormatError(\"No domain.\");\n    }\n    if (!range) {\n      throw new FormatError(\"No range.\");\n    }\n    const lexer = new PostScriptLexer(fn);\n    const parser = new PostScriptParser(lexer);\n    const code = parser.parse();\n    if (isEvalSupported && FeatureTest.isEvalSupported) {\n      const compiled = new PostScriptCompiler().compile(code, domain, range);\n      if (compiled) {\n        return new Function(\"src\", \"srcOffset\", \"dest\", \"destOffset\", compiled);\n      }\n    }\n    info(\"Unable to compile PS function\");\n    const numOutputs = range.length >> 1;\n    const numInputs = domain.length >> 1;\n    const evaluator = new PostScriptEvaluator(code);\n    const cache = Object.create(null);\n    const MAX_CACHE_SIZE = 2048 * 4;\n    let cache_available = MAX_CACHE_SIZE;\n    const tmpBuf = new Float32Array(numInputs);\n    return function constructPostScriptFn(src, srcOffset, dest, destOffset) {\n      let i, value;\n      let key = \"\";\n      const input = tmpBuf;\n      for (i = 0; i < numInputs; i++) {\n        value = src[srcOffset + i];\n        input[i] = value;\n        key += value + \"_\";\n      }\n      const cachedValue = cache[key];\n      if (cachedValue !== undefined) {\n        dest.set(cachedValue, destOffset);\n        return;\n      }\n      const output = new Float32Array(numOutputs);\n      const stack = evaluator.execute(input);\n      const stackIndex = stack.length - numOutputs;\n      for (i = 0; i < numOutputs; i++) {\n        value = stack[stackIndex + i];\n        let bound = range[i * 2];\n        if (value < bound) {\n          value = bound;\n        } else {\n          bound = range[i * 2 + 1];\n          if (value > bound) {\n            value = bound;\n          }\n        }\n        output[i] = value;\n      }\n      if (cache_available > 0) {\n        cache_available--;\n        cache[key] = output;\n      }\n      dest.set(output, destOffset);\n    };\n  }\n}\nfunction isPDFFunction(v) {\n  let fnDict;\n  if (v instanceof Dict) {\n    fnDict = v;\n  } else if (v instanceof BaseStream) {\n    fnDict = v.dict;\n  } else {\n    return false;\n  }\n  return fnDict.has(\"FunctionType\");\n}\nclass PostScriptStack {\n  static MAX_STACK_SIZE = 100;\n  constructor(initialStack) {\n    this.stack = initialStack ? Array.from(initialStack) : [];\n  }\n  push(value) {\n    if (this.stack.length >= PostScriptStack.MAX_STACK_SIZE) {\n      throw new Error(\"PostScript function stack overflow.\");\n    }\n    this.stack.push(value);\n  }\n  pop() {\n    if (this.stack.length <= 0) {\n      throw new Error(\"PostScript function stack underflow.\");\n    }\n    return this.stack.pop();\n  }\n  copy(n) {\n    if (this.stack.length + n >= PostScriptStack.MAX_STACK_SIZE) {\n      throw new Error(\"PostScript function stack overflow.\");\n    }\n    const stack = this.stack;\n    for (let i = stack.length - n, j = n - 1; j >= 0; j--, i++) {\n      stack.push(stack[i]);\n    }\n  }\n  index(n) {\n    this.push(this.stack[this.stack.length - n - 1]);\n  }\n  roll(n, p) {\n    const stack = this.stack;\n    const l = stack.length - n;\n    const r = stack.length - 1;\n    const c = l + (p - Math.floor(p / n) * n);\n    for (let i = l, j = r; i < j; i++, j--) {\n      const t = stack[i];\n      stack[i] = stack[j];\n      stack[j] = t;\n    }\n    for (let i = l, j = c - 1; i < j; i++, j--) {\n      const t = stack[i];\n      stack[i] = stack[j];\n      stack[j] = t;\n    }\n    for (let i = c, j = r; i < j; i++, j--) {\n      const t = stack[i];\n      stack[i] = stack[j];\n      stack[j] = t;\n    }\n  }\n}\nclass PostScriptEvaluator {\n  constructor(operators) {\n    this.operators = operators;\n  }\n  execute(initialStack) {\n    const stack = new PostScriptStack(initialStack);\n    let counter = 0;\n    const operators = this.operators;\n    const length = operators.length;\n    let operator, a, b;\n    while (counter < length) {\n      operator = operators[counter++];\n      if (typeof operator === \"number\") {\n        stack.push(operator);\n        continue;\n      }\n      switch (operator) {\n        case \"jz\":\n          b = stack.pop();\n          a = stack.pop();\n          if (!a) {\n            counter = b;\n          }\n          break;\n        case \"j\":\n          a = stack.pop();\n          counter = a;\n          break;\n        case \"abs\":\n          a = stack.pop();\n          stack.push(Math.abs(a));\n          break;\n        case \"add\":\n          b = stack.pop();\n          a = stack.pop();\n          stack.push(a + b);\n          break;\n        case \"and\":\n          b = stack.pop();\n          a = stack.pop();\n          if (typeof a === \"boolean\" && typeof b === \"boolean\") {\n            stack.push(a && b);\n          } else {\n            stack.push(a & b);\n          }\n          break;\n        case \"atan\":\n          b = stack.pop();\n          a = stack.pop();\n          a = Math.atan2(a, b) / Math.PI * 180;\n          if (a < 0) {\n            a += 360;\n          }\n          stack.push(a);\n          break;\n        case \"bitshift\":\n          b = stack.pop();\n          a = stack.pop();\n          if (a > 0) {\n            stack.push(a << b);\n          } else {\n            stack.push(a >> b);\n          }\n          break;\n        case \"ceiling\":\n          a = stack.pop();\n          stack.push(Math.ceil(a));\n          break;\n        case \"copy\":\n          a = stack.pop();\n          stack.copy(a);\n          break;\n        case \"cos\":\n          a = stack.pop();\n          stack.push(Math.cos(a % 360 / 180 * Math.PI));\n          break;\n        case \"cvi\":\n          a = stack.pop() | 0;\n          stack.push(a);\n          break;\n        case \"cvr\":\n          break;\n        case \"div\":\n          b = stack.pop();\n          a = stack.pop();\n          stack.push(a / b);\n          break;\n        case \"dup\":\n          stack.copy(1);\n          break;\n        case \"eq\":\n          b = stack.pop();\n          a = stack.pop();\n          stack.push(a === b);\n          break;\n        case \"exch\":\n          stack.roll(2, 1);\n          break;\n        case \"exp\":\n          b = stack.pop();\n          a = stack.pop();\n          stack.push(a ** b);\n          break;\n        case \"false\":\n          stack.push(false);\n          break;\n        case \"floor\":\n          a = stack.pop();\n          stack.push(Math.floor(a));\n          break;\n        case \"ge\":\n          b = stack.pop();\n          a = stack.pop();\n          stack.push(a >= b);\n          break;\n        case \"gt\":\n          b = stack.pop();\n          a = stack.pop();\n          stack.push(a > b);\n          break;\n        case \"idiv\":\n          b = stack.pop();\n          a = stack.pop();\n          stack.push(a / b | 0);\n          break;\n        case \"index\":\n          a = stack.pop();\n          stack.index(a);\n          break;\n        case \"le\":\n          b = stack.pop();\n          a = stack.pop();\n          stack.push(a <= b);\n          break;\n        case \"ln\":\n          a = stack.pop();\n          stack.push(Math.log(a));\n          break;\n        case \"log\":\n          a = stack.pop();\n          stack.push(Math.log10(a));\n          break;\n        case \"lt\":\n          b = stack.pop();\n          a = stack.pop();\n          stack.push(a < b);\n          break;\n        case \"mod\":\n          b = stack.pop();\n          a = stack.pop();\n          stack.push(a % b);\n          break;\n        case \"mul\":\n          b = stack.pop();\n          a = stack.pop();\n          stack.push(a * b);\n          break;\n        case \"ne\":\n          b = stack.pop();\n          a = stack.pop();\n          stack.push(a !== b);\n          break;\n        case \"neg\":\n          a = stack.pop();\n          stack.push(-a);\n          break;\n        case \"not\":\n          a = stack.pop();\n          if (typeof a === \"boolean\") {\n            stack.push(!a);\n          } else {\n            stack.push(~a);\n          }\n          break;\n        case \"or\":\n          b = stack.pop();\n          a = stack.pop();\n          if (typeof a === \"boolean\" && typeof b === \"boolean\") {\n            stack.push(a || b);\n          } else {\n            stack.push(a | b);\n          }\n          break;\n        case \"pop\":\n          stack.pop();\n          break;\n        case \"roll\":\n          b = stack.pop();\n          a = stack.pop();\n          stack.roll(a, b);\n          break;\n        case \"round\":\n          a = stack.pop();\n          stack.push(Math.round(a));\n          break;\n        case \"sin\":\n          a = stack.pop();\n          stack.push(Math.sin(a % 360 / 180 * Math.PI));\n          break;\n        case \"sqrt\":\n          a = stack.pop();\n          stack.push(Math.sqrt(a));\n          break;\n        case \"sub\":\n          b = stack.pop();\n          a = stack.pop();\n          stack.push(a - b);\n          break;\n        case \"true\":\n          stack.push(true);\n          break;\n        case \"truncate\":\n          a = stack.pop();\n          a = a < 0 ? Math.ceil(a) : Math.floor(a);\n          stack.push(a);\n          break;\n        case \"xor\":\n          b = stack.pop();\n          a = stack.pop();\n          if (typeof a === \"boolean\" && typeof b === \"boolean\") {\n            stack.push(a !== b);\n          } else {\n            stack.push(a ^ b);\n          }\n          break;\n        default:\n          throw new FormatError(`Unknown operator ${operator}`);\n      }\n    }\n    return stack.stack;\n  }\n}\nclass AstNode {\n  constructor(type) {\n    this.type = type;\n  }\n  visit(visitor) {\n    unreachable(\"abstract method\");\n  }\n}\nclass AstArgument extends AstNode {\n  constructor(index, min, max) {\n    super(\"args\");\n    this.index = index;\n    this.min = min;\n    this.max = max;\n  }\n  visit(visitor) {\n    visitor.visitArgument(this);\n  }\n}\nclass AstLiteral extends AstNode {\n  constructor(number) {\n    super(\"literal\");\n    this.number = number;\n    this.min = number;\n    this.max = number;\n  }\n  visit(visitor) {\n    visitor.visitLiteral(this);\n  }\n}\nclass AstBinaryOperation extends AstNode {\n  constructor(op, arg1, arg2, min, max) {\n    super(\"binary\");\n    this.op = op;\n    this.arg1 = arg1;\n    this.arg2 = arg2;\n    this.min = min;\n    this.max = max;\n  }\n  visit(visitor) {\n    visitor.visitBinaryOperation(this);\n  }\n}\nclass AstMin extends AstNode {\n  constructor(arg, max) {\n    super(\"max\");\n    this.arg = arg;\n    this.min = arg.min;\n    this.max = max;\n  }\n  visit(visitor) {\n    visitor.visitMin(this);\n  }\n}\nclass AstVariable extends AstNode {\n  constructor(index, min, max) {\n    super(\"var\");\n    this.index = index;\n    this.min = min;\n    this.max = max;\n  }\n  visit(visitor) {\n    visitor.visitVariable(this);\n  }\n}\nclass AstVariableDefinition extends AstNode {\n  constructor(variable, arg) {\n    super(\"definition\");\n    this.variable = variable;\n    this.arg = arg;\n  }\n  visit(visitor) {\n    visitor.visitVariableDefinition(this);\n  }\n}\nclass ExpressionBuilderVisitor {\n  constructor() {\n    this.parts = [];\n  }\n  visitArgument(arg) {\n    this.parts.push(\"Math.max(\", arg.min, \", Math.min(\", arg.max, \", src[srcOffset + \", arg.index, \"]))\");\n  }\n  visitVariable(variable) {\n    this.parts.push(\"v\", variable.index);\n  }\n  visitLiteral(literal) {\n    this.parts.push(literal.number);\n  }\n  visitBinaryOperation(operation) {\n    this.parts.push(\"(\");\n    operation.arg1.visit(this);\n    this.parts.push(\" \", operation.op, \" \");\n    operation.arg2.visit(this);\n    this.parts.push(\")\");\n  }\n  visitVariableDefinition(definition) {\n    this.parts.push(\"var \");\n    definition.variable.visit(this);\n    this.parts.push(\" = \");\n    definition.arg.visit(this);\n    this.parts.push(\";\");\n  }\n  visitMin(max) {\n    this.parts.push(\"Math.min(\");\n    max.arg.visit(this);\n    this.parts.push(\", \", max.max, \")\");\n  }\n  toString() {\n    return this.parts.join(\"\");\n  }\n}\nfunction buildAddOperation(num1, num2) {\n  if (num2.type === \"literal\" && num2.number === 0) {\n    return num1;\n  }\n  if (num1.type === \"literal\" && num1.number === 0) {\n    return num2;\n  }\n  if (num2.type === \"literal\" && num1.type === \"literal\") {\n    return new AstLiteral(num1.number + num2.number);\n  }\n  return new AstBinaryOperation(\"+\", num1, num2, num1.min + num2.min, num1.max + num2.max);\n}\nfunction buildMulOperation(num1, num2) {\n  if (num2.type === \"literal\") {\n    if (num2.number === 0) {\n      return new AstLiteral(0);\n    } else if (num2.number === 1) {\n      return num1;\n    } else if (num1.type === \"literal\") {\n      return new AstLiteral(num1.number * num2.number);\n    }\n  }\n  if (num1.type === \"literal\") {\n    if (num1.number === 0) {\n      return new AstLiteral(0);\n    } else if (num1.number === 1) {\n      return num2;\n    }\n  }\n  const min = Math.min(num1.min * num2.min, num1.min * num2.max, num1.max * num2.min, num1.max * num2.max);\n  const max = Math.max(num1.min * num2.min, num1.min * num2.max, num1.max * num2.min, num1.max * num2.max);\n  return new AstBinaryOperation(\"*\", num1, num2, min, max);\n}\nfunction buildSubOperation(num1, num2) {\n  if (num2.type === \"literal\") {\n    if (num2.number === 0) {\n      return num1;\n    } else if (num1.type === \"literal\") {\n      return new AstLiteral(num1.number - num2.number);\n    }\n  }\n  if (num2.type === \"binary\" && num2.op === \"-\" && num1.type === \"literal\" && num1.number === 1 && num2.arg1.type === \"literal\" && num2.arg1.number === 1) {\n    return num2.arg2;\n  }\n  return new AstBinaryOperation(\"-\", num1, num2, num1.min - num2.max, num1.max - num2.min);\n}\nfunction buildMinOperation(num1, max) {\n  if (num1.min >= max) {\n    return new AstLiteral(max);\n  } else if (num1.max <= max) {\n    return num1;\n  }\n  return new AstMin(num1, max);\n}\nclass PostScriptCompiler {\n  compile(code, domain, range) {\n    const stack = [];\n    const instructions = [];\n    const inputSize = domain.length >> 1,\n      outputSize = range.length >> 1;\n    let lastRegister = 0;\n    let n, j;\n    let num1, num2, ast1, ast2, tmpVar, item;\n    for (let i = 0; i < inputSize; i++) {\n      stack.push(new AstArgument(i, domain[i * 2], domain[i * 2 + 1]));\n    }\n    for (let i = 0, ii = code.length; i < ii; i++) {\n      item = code[i];\n      if (typeof item === \"number\") {\n        stack.push(new AstLiteral(item));\n        continue;\n      }\n      switch (item) {\n        case \"add\":\n          if (stack.length < 2) {\n            return null;\n          }\n          num2 = stack.pop();\n          num1 = stack.pop();\n          stack.push(buildAddOperation(num1, num2));\n          break;\n        case \"cvr\":\n          if (stack.length < 1) {\n            return null;\n          }\n          break;\n        case \"mul\":\n          if (stack.length < 2) {\n            return null;\n          }\n          num2 = stack.pop();\n          num1 = stack.pop();\n          stack.push(buildMulOperation(num1, num2));\n          break;\n        case \"sub\":\n          if (stack.length < 2) {\n            return null;\n          }\n          num2 = stack.pop();\n          num1 = stack.pop();\n          stack.push(buildSubOperation(num1, num2));\n          break;\n        case \"exch\":\n          if (stack.length < 2) {\n            return null;\n          }\n          ast1 = stack.pop();\n          ast2 = stack.pop();\n          stack.push(ast1, ast2);\n          break;\n        case \"pop\":\n          if (stack.length < 1) {\n            return null;\n          }\n          stack.pop();\n          break;\n        case \"index\":\n          if (stack.length < 1) {\n            return null;\n          }\n          num1 = stack.pop();\n          if (num1.type !== \"literal\") {\n            return null;\n          }\n          n = num1.number;\n          if (n < 0 || !Number.isInteger(n) || stack.length < n) {\n            return null;\n          }\n          ast1 = stack[stack.length - n - 1];\n          if (ast1.type === \"literal\" || ast1.type === \"var\") {\n            stack.push(ast1);\n            break;\n          }\n          tmpVar = new AstVariable(lastRegister++, ast1.min, ast1.max);\n          stack[stack.length - n - 1] = tmpVar;\n          stack.push(tmpVar);\n          instructions.push(new AstVariableDefinition(tmpVar, ast1));\n          break;\n        case \"dup\":\n          if (stack.length < 1) {\n            return null;\n          }\n          if (typeof code[i + 1] === \"number\" && code[i + 2] === \"gt\" && code[i + 3] === i + 7 && code[i + 4] === \"jz\" && code[i + 5] === \"pop\" && code[i + 6] === code[i + 1]) {\n            num1 = stack.pop();\n            stack.push(buildMinOperation(num1, code[i + 1]));\n            i += 6;\n            break;\n          }\n          ast1 = stack.at(-1);\n          if (ast1.type === \"literal\" || ast1.type === \"var\") {\n            stack.push(ast1);\n            break;\n          }\n          tmpVar = new AstVariable(lastRegister++, ast1.min, ast1.max);\n          stack[stack.length - 1] = tmpVar;\n          stack.push(tmpVar);\n          instructions.push(new AstVariableDefinition(tmpVar, ast1));\n          break;\n        case \"roll\":\n          if (stack.length < 2) {\n            return null;\n          }\n          num2 = stack.pop();\n          num1 = stack.pop();\n          if (num2.type !== \"literal\" || num1.type !== \"literal\") {\n            return null;\n          }\n          j = num2.number;\n          n = num1.number;\n          if (n <= 0 || !Number.isInteger(n) || !Number.isInteger(j) || stack.length < n) {\n            return null;\n          }\n          j = (j % n + n) % n;\n          if (j === 0) {\n            break;\n          }\n          stack.push(...stack.splice(stack.length - n, n - j));\n          break;\n        default:\n          return null;\n      }\n    }\n    if (stack.length !== outputSize) {\n      return null;\n    }\n    const result = [];\n    for (const instruction of instructions) {\n      const statementBuilder = new ExpressionBuilderVisitor();\n      instruction.visit(statementBuilder);\n      result.push(statementBuilder.toString());\n    }\n    for (let i = 0, ii = stack.length; i < ii; i++) {\n      const expr = stack[i],\n        statementBuilder = new ExpressionBuilderVisitor();\n      expr.visit(statementBuilder);\n      const min = range[i * 2],\n        max = range[i * 2 + 1];\n      const out = [statementBuilder.toString()];\n      if (min > expr.min) {\n        out.unshift(\"Math.max(\", min, \", \");\n        out.push(\")\");\n      }\n      if (max < expr.max) {\n        out.unshift(\"Math.min(\", max, \", \");\n        out.push(\")\");\n      }\n      out.unshift(\"dest[destOffset + \", i, \"] = \");\n      out.push(\";\");\n      result.push(out.join(\"\"));\n    }\n    return result.join(\"\\n\");\n  }\n}\n\n;// ./src/core/bidi.js\n\nconst baseTypes = [\"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"S\", \"B\", \"S\", \"WS\", \"B\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"B\", \"B\", \"B\", \"S\", \"WS\", \"ON\", \"ON\", \"ET\", \"ET\", \"ET\", \"ON\", \"ON\", \"ON\", \"ON\", \"ON\", \"ES\", \"CS\", \"ES\", \"CS\", \"CS\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"CS\", \"ON\", \"ON\", \"ON\", \"ON\", \"ON\", \"ON\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"ON\", \"ON\", \"ON\", \"ON\", \"ON\", \"ON\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"ON\", \"ON\", \"ON\", \"ON\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"B\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"CS\", \"ON\", \"ET\", \"ET\", \"ET\", \"ET\", \"ON\", \"ON\", \"ON\", \"ON\", \"L\", \"ON\", \"ON\", \"BN\", \"ON\", \"ON\", \"ET\", \"ET\", \"EN\", \"EN\", \"ON\", \"L\", \"ON\", \"ON\", \"ON\", \"EN\", \"L\", \"ON\", \"ON\", \"ON\", \"ON\", \"ON\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"ON\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"ON\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\"];\nconst arabicTypes = [\"AN\", \"AN\", \"AN\", \"AN\", \"AN\", \"AN\", \"ON\", \"ON\", \"AL\", \"ET\", \"ET\", \"AL\", \"CS\", \"AL\", \"ON\", \"ON\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"AL\", \"AL\", \"\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"AN\", \"AN\", \"AN\", \"AN\", \"AN\", \"AN\", \"AN\", \"AN\", \"AN\", \"AN\", \"ET\", \"AN\", \"AN\", \"AL\", \"AL\", \"AL\", \"NSM\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"AN\", \"ON\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"AL\", \"AL\", \"NSM\", \"NSM\", \"ON\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"AL\", \"AL\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\"];\nfunction isOdd(i) {\n  return (i & 1) !== 0;\n}\nfunction isEven(i) {\n  return (i & 1) === 0;\n}\nfunction findUnequal(arr, start, value) {\n  let j, jj;\n  for (j = start, jj = arr.length; j < jj; ++j) {\n    if (arr[j] !== value) {\n      return j;\n    }\n  }\n  return j;\n}\nfunction setValues(arr, start, end, value) {\n  for (let j = start; j < end; ++j) {\n    arr[j] = value;\n  }\n}\nfunction reverseValues(arr, start, end) {\n  for (let i = start, j = end - 1; i < j; ++i, --j) {\n    const temp = arr[i];\n    arr[i] = arr[j];\n    arr[j] = temp;\n  }\n}\nfunction createBidiText(str, isLTR, vertical = false) {\n  let dir = \"ltr\";\n  if (vertical) {\n    dir = \"ttb\";\n  } else if (!isLTR) {\n    dir = \"rtl\";\n  }\n  return {\n    str,\n    dir\n  };\n}\nconst chars = [];\nconst types = [];\nfunction bidi(str, startLevel = -1, vertical = false) {\n  let isLTR = true;\n  const strLength = str.length;\n  if (strLength === 0 || vertical) {\n    return createBidiText(str, isLTR, vertical);\n  }\n  chars.length = strLength;\n  types.length = strLength;\n  let numBidi = 0;\n  let i, ii;\n  for (i = 0; i < strLength; ++i) {\n    chars[i] = str.charAt(i);\n    const charCode = str.charCodeAt(i);\n    let charType = \"L\";\n    if (charCode <= 0x00ff) {\n      charType = baseTypes[charCode];\n    } else if (0x0590 <= charCode && charCode <= 0x05f4) {\n      charType = \"R\";\n    } else if (0x0600 <= charCode && charCode <= 0x06ff) {\n      charType = arabicTypes[charCode & 0xff];\n      if (!charType) {\n        warn(\"Bidi: invalid Unicode character \" + charCode.toString(16));\n      }\n    } else if (0x0700 <= charCode && charCode <= 0x08ac || 0xfb50 <= charCode && charCode <= 0xfdff || 0xfe70 <= charCode && charCode <= 0xfeff) {\n      charType = \"AL\";\n    }\n    if (charType === \"R\" || charType === \"AL\" || charType === \"AN\") {\n      numBidi++;\n    }\n    types[i] = charType;\n  }\n  if (numBidi === 0) {\n    isLTR = true;\n    return createBidiText(str, isLTR);\n  }\n  if (startLevel === -1) {\n    if (numBidi / strLength < 0.3 && strLength > 4) {\n      isLTR = true;\n      startLevel = 0;\n    } else {\n      isLTR = false;\n      startLevel = 1;\n    }\n  }\n  const levels = [];\n  for (i = 0; i < strLength; ++i) {\n    levels[i] = startLevel;\n  }\n  const e = isOdd(startLevel) ? \"R\" : \"L\";\n  const sor = e;\n  const eor = sor;\n  let lastType = sor;\n  for (i = 0; i < strLength; ++i) {\n    if (types[i] === \"NSM\") {\n      types[i] = lastType;\n    } else {\n      lastType = types[i];\n    }\n  }\n  lastType = sor;\n  let t;\n  for (i = 0; i < strLength; ++i) {\n    t = types[i];\n    if (t === \"EN\") {\n      types[i] = lastType === \"AL\" ? \"AN\" : \"EN\";\n    } else if (t === \"R\" || t === \"L\" || t === \"AL\") {\n      lastType = t;\n    }\n  }\n  for (i = 0; i < strLength; ++i) {\n    t = types[i];\n    if (t === \"AL\") {\n      types[i] = \"R\";\n    }\n  }\n  for (i = 1; i < strLength - 1; ++i) {\n    if (types[i] === \"ES\" && types[i - 1] === \"EN\" && types[i + 1] === \"EN\") {\n      types[i] = \"EN\";\n    }\n    if (types[i] === \"CS\" && (types[i - 1] === \"EN\" || types[i - 1] === \"AN\") && types[i + 1] === types[i - 1]) {\n      types[i] = types[i - 1];\n    }\n  }\n  for (i = 0; i < strLength; ++i) {\n    if (types[i] === \"EN\") {\n      for (let j = i - 1; j >= 0; --j) {\n        if (types[j] !== \"ET\") {\n          break;\n        }\n        types[j] = \"EN\";\n      }\n      for (let j = i + 1; j < strLength; ++j) {\n        if (types[j] !== \"ET\") {\n          break;\n        }\n        types[j] = \"EN\";\n      }\n    }\n  }\n  for (i = 0; i < strLength; ++i) {\n    t = types[i];\n    if (t === \"WS\" || t === \"ES\" || t === \"ET\" || t === \"CS\") {\n      types[i] = \"ON\";\n    }\n  }\n  lastType = sor;\n  for (i = 0; i < strLength; ++i) {\n    t = types[i];\n    if (t === \"EN\") {\n      types[i] = lastType === \"L\" ? \"L\" : \"EN\";\n    } else if (t === \"R\" || t === \"L\") {\n      lastType = t;\n    }\n  }\n  for (i = 0; i < strLength; ++i) {\n    if (types[i] === \"ON\") {\n      const end = findUnequal(types, i + 1, \"ON\");\n      let before = sor;\n      if (i > 0) {\n        before = types[i - 1];\n      }\n      let after = eor;\n      if (end + 1 < strLength) {\n        after = types[end + 1];\n      }\n      if (before !== \"L\") {\n        before = \"R\";\n      }\n      if (after !== \"L\") {\n        after = \"R\";\n      }\n      if (before === after) {\n        setValues(types, i, end, before);\n      }\n      i = end - 1;\n    }\n  }\n  for (i = 0; i < strLength; ++i) {\n    if (types[i] === \"ON\") {\n      types[i] = e;\n    }\n  }\n  for (i = 0; i < strLength; ++i) {\n    t = types[i];\n    if (isEven(levels[i])) {\n      if (t === \"R\") {\n        levels[i] += 1;\n      } else if (t === \"AN\" || t === \"EN\") {\n        levels[i] += 2;\n      }\n    } else if (t === \"L\" || t === \"AN\" || t === \"EN\") {\n      levels[i] += 1;\n    }\n  }\n  let highestLevel = -1;\n  let lowestOddLevel = 99;\n  let level;\n  for (i = 0, ii = levels.length; i < ii; ++i) {\n    level = levels[i];\n    if (highestLevel < level) {\n      highestLevel = level;\n    }\n    if (lowestOddLevel > level && isOdd(level)) {\n      lowestOddLevel = level;\n    }\n  }\n  for (level = highestLevel; level >= lowestOddLevel; --level) {\n    let start = -1;\n    for (i = 0, ii = levels.length; i < ii; ++i) {\n      if (levels[i] < level) {\n        if (start >= 0) {\n          reverseValues(chars, start, i);\n          start = -1;\n        }\n      } else if (start < 0) {\n        start = i;\n      }\n    }\n    if (start >= 0) {\n      reverseValues(chars, start, levels.length);\n    }\n  }\n  for (i = 0, ii = chars.length; i < ii; ++i) {\n    const ch = chars[i];\n    if (ch === \"<\" || ch === \">\") {\n      chars[i] = \"\";\n    }\n  }\n  return createBidiText(chars.join(\"\"), isLTR);\n}\n\n;// ./src/core/font_substitutions.js\n\n\nconst NORMAL = {\n  style: \"normal\",\n  weight: \"normal\"\n};\nconst BOLD = {\n  style: \"normal\",\n  weight: \"bold\"\n};\nconst ITALIC = {\n  style: \"italic\",\n  weight: \"normal\"\n};\nconst BOLDITALIC = {\n  style: \"italic\",\n  weight: \"bold\"\n};\nconst substitutionMap = new Map([[\"Times-Roman\", {\n  local: [\"Times New Roman\", \"Times-Roman\", \"Times\", \"Liberation Serif\", \"Nimbus Roman\", \"Nimbus Roman L\", \"Tinos\", \"Thorndale\", \"TeX Gyre Termes\", \"FreeSerif\", \"Linux Libertine O\", \"Libertinus Serif\", \"DejaVu Serif\", \"Bitstream Vera Serif\", \"Ubuntu\"],\n  style: NORMAL,\n  ultimate: \"serif\"\n}], [\"Times-Bold\", {\n  alias: \"Times-Roman\",\n  style: BOLD,\n  ultimate: \"serif\"\n}], [\"Times-Italic\", {\n  alias: \"Times-Roman\",\n  style: ITALIC,\n  ultimate: \"serif\"\n}], [\"Times-BoldItalic\", {\n  alias: \"Times-Roman\",\n  style: BOLDITALIC,\n  ultimate: \"serif\"\n}], [\"Helvetica\", {\n  local: [\"Helvetica\", \"Helvetica Neue\", \"Arial\", \"Arial Nova\", \"Liberation Sans\", \"Arimo\", \"Nimbus Sans\", \"Nimbus Sans L\", \"A030\", \"TeX Gyre Heros\", \"FreeSans\", \"DejaVu Sans\", \"Albany\", \"Bitstream Vera Sans\", \"Arial Unicode MS\", \"Microsoft Sans Serif\", \"Apple Symbols\", \"Cantarell\"],\n  path: \"LiberationSans-Regular.ttf\",\n  style: NORMAL,\n  ultimate: \"sans-serif\"\n}], [\"Helvetica-Bold\", {\n  alias: \"Helvetica\",\n  path: \"LiberationSans-Bold.ttf\",\n  style: BOLD,\n  ultimate: \"sans-serif\"\n}], [\"Helvetica-Oblique\", {\n  alias: \"Helvetica\",\n  path: \"LiberationSans-Italic.ttf\",\n  style: ITALIC,\n  ultimate: \"sans-serif\"\n}], [\"Helvetica-BoldOblique\", {\n  alias: \"Helvetica\",\n  path: \"LiberationSans-BoldItalic.ttf\",\n  style: BOLDITALIC,\n  ultimate: \"sans-serif\"\n}], [\"Courier\", {\n  local: [\"Courier\", \"Courier New\", \"Liberation Mono\", \"Nimbus Mono\", \"Nimbus Mono L\", \"Cousine\", \"Cumberland\", \"TeX Gyre Cursor\", \"FreeMono\", \"Linux Libertine Mono O\", \"Libertinus Mono\"],\n  style: NORMAL,\n  ultimate: \"monospace\"\n}], [\"Courier-Bold\", {\n  alias: \"Courier\",\n  style: BOLD,\n  ultimate: \"monospace\"\n}], [\"Courier-Oblique\", {\n  alias: \"Courier\",\n  style: ITALIC,\n  ultimate: \"monospace\"\n}], [\"Courier-BoldOblique\", {\n  alias: \"Courier\",\n  style: BOLDITALIC,\n  ultimate: \"monospace\"\n}], [\"ArialBlack\", {\n  local: [\"Arial Black\"],\n  style: {\n    style: \"normal\",\n    weight: \"900\"\n  },\n  fallback: \"Helvetica-Bold\"\n}], [\"ArialBlack-Bold\", {\n  alias: \"ArialBlack\"\n}], [\"ArialBlack-Italic\", {\n  alias: \"ArialBlack\",\n  style: {\n    style: \"italic\",\n    weight: \"900\"\n  },\n  fallback: \"Helvetica-BoldOblique\"\n}], [\"ArialBlack-BoldItalic\", {\n  alias: \"ArialBlack-Italic\"\n}], [\"ArialNarrow\", {\n  local: [\"Arial Narrow\", \"Liberation Sans Narrow\", \"Helvetica Condensed\", \"Nimbus Sans Narrow\", \"TeX Gyre Heros Cn\"],\n  style: NORMAL,\n  fallback: \"Helvetica\"\n}], [\"ArialNarrow-Bold\", {\n  alias: \"ArialNarrow\",\n  style: BOLD,\n  fallback: \"Helvetica-Bold\"\n}], [\"ArialNarrow-Italic\", {\n  alias: \"ArialNarrow\",\n  style: ITALIC,\n  fallback: \"Helvetica-Oblique\"\n}], [\"ArialNarrow-BoldItalic\", {\n  alias: \"ArialNarrow\",\n  style: BOLDITALIC,\n  fallback: \"Helvetica-BoldOblique\"\n}], [\"Calibri\", {\n  local: [\"Calibri\", \"Carlito\"],\n  style: NORMAL,\n  fallback: \"Helvetica\"\n}], [\"Calibri-Bold\", {\n  alias: \"Calibri\",\n  style: BOLD,\n  fallback: \"Helvetica-Bold\"\n}], [\"Calibri-Italic\", {\n  alias: \"Calibri\",\n  style: ITALIC,\n  fallback: \"Helvetica-Oblique\"\n}], [\"Calibri-BoldItalic\", {\n  alias: \"Calibri\",\n  style: BOLDITALIC,\n  fallback: \"Helvetica-BoldOblique\"\n}], [\"Wingdings\", {\n  local: [\"Wingdings\", \"URW Dingbats\"],\n  style: NORMAL\n}], [\"Wingdings-Regular\", {\n  alias: \"Wingdings\"\n}], [\"Wingdings-Bold\", {\n  alias: \"Wingdings\"\n}]]);\nconst fontAliases = new Map([[\"Arial-Black\", \"ArialBlack\"]]);\nfunction getStyleToAppend(style) {\n  switch (style) {\n    case BOLD:\n      return \"Bold\";\n    case ITALIC:\n      return \"Italic\";\n    case BOLDITALIC:\n      return \"Bold Italic\";\n    default:\n      if (style?.weight === \"bold\") {\n        return \"Bold\";\n      }\n      if (style?.style === \"italic\") {\n        return \"Italic\";\n      }\n  }\n  return \"\";\n}\nfunction getFamilyName(str) {\n  const keywords = new Set([\"thin\", \"extralight\", \"ultralight\", \"demilight\", \"semilight\", \"light\", \"book\", \"regular\", \"normal\", \"medium\", \"demibold\", \"semibold\", \"bold\", \"extrabold\", \"ultrabold\", \"black\", \"heavy\", \"extrablack\", \"ultrablack\", \"roman\", \"italic\", \"oblique\", \"ultracondensed\", \"extracondensed\", \"condensed\", \"semicondensed\", \"normal\", \"semiexpanded\", \"expanded\", \"extraexpanded\", \"ultraexpanded\", \"bolditalic\"]);\n  return str.split(/[- ,+]+/g).filter(tok => !keywords.has(tok.toLowerCase())).join(\" \");\n}\nfunction generateFont({\n  alias,\n  local,\n  path,\n  fallback,\n  style,\n  ultimate\n}, src, localFontPath, useFallback = true, usePath = true, append = \"\") {\n  const result = {\n    style: null,\n    ultimate: null\n  };\n  if (local) {\n    const extra = append ? ` ${append}` : \"\";\n    for (const name of local) {\n      src.push(`local(${name}${extra})`);\n    }\n  }\n  if (alias) {\n    const substitution = substitutionMap.get(alias);\n    const aliasAppend = append || getStyleToAppend(style);\n    Object.assign(result, generateFont(substitution, src, localFontPath, useFallback && !fallback, usePath && !path, aliasAppend));\n  }\n  if (style) {\n    result.style = style;\n  }\n  if (ultimate) {\n    result.ultimate = ultimate;\n  }\n  if (useFallback && fallback) {\n    const fallbackInfo = substitutionMap.get(fallback);\n    const {\n      ultimate: fallbackUltimate\n    } = generateFont(fallbackInfo, src, localFontPath, useFallback, usePath && !path, append);\n    result.ultimate ||= fallbackUltimate;\n  }\n  if (usePath && path && localFontPath) {\n    src.push(`url(${localFontPath}${path})`);\n  }\n  return result;\n}\nfunction getFontSubstitution(systemFontCache, idFactory, localFontPath, baseFontName, standardFontName) {\n  if (baseFontName.startsWith(\"InvalidPDFjsFont_\")) {\n    return null;\n  }\n  baseFontName = normalizeFontName(baseFontName);\n  const key = baseFontName;\n  let substitutionInfo = systemFontCache.get(key);\n  if (substitutionInfo) {\n    return substitutionInfo;\n  }\n  let substitution = substitutionMap.get(baseFontName);\n  if (!substitution) {\n    for (const [alias, subst] of fontAliases) {\n      if (baseFontName.startsWith(alias)) {\n        baseFontName = `${subst}${baseFontName.substring(alias.length)}`;\n        substitution = substitutionMap.get(baseFontName);\n        break;\n      }\n    }\n  }\n  let mustAddBaseFont = false;\n  if (!substitution) {\n    substitution = substitutionMap.get(standardFontName);\n    mustAddBaseFont = true;\n  }\n  const loadedName = `${idFactory.getDocId()}_s${idFactory.createFontId()}`;\n  if (!substitution) {\n    if (!validateFontName(baseFontName)) {\n      systemFontCache.set(key, null);\n      return null;\n    }\n    const bold = /bold/gi.test(baseFontName);\n    const italic = /oblique|italic/gi.test(baseFontName);\n    const style = bold && italic && BOLDITALIC || bold && BOLD || italic && ITALIC || NORMAL;\n    substitutionInfo = {\n      css: `\"${getFamilyName(baseFontName)}\",${loadedName}`,\n      guessFallback: true,\n      loadedName,\n      baseFontName,\n      src: `local(${baseFontName})`,\n      style\n    };\n    systemFontCache.set(key, substitutionInfo);\n    return substitutionInfo;\n  }\n  const src = [];\n  if (mustAddBaseFont && validateFontName(baseFontName)) {\n    src.push(`local(${baseFontName})`);\n  }\n  const {\n    style,\n    ultimate\n  } = generateFont(substitution, src, localFontPath);\n  const guessFallback = ultimate === null;\n  const fallback = guessFallback ? \"\" : `,${ultimate}`;\n  substitutionInfo = {\n    css: `\"${getFamilyName(baseFontName)}\",${loadedName}${fallback}`,\n    guessFallback,\n    loadedName,\n    baseFontName,\n    src: src.join(\",\"),\n    style\n  };\n  systemFontCache.set(key, substitutionInfo);\n  return substitutionInfo;\n}\n\n;// ./src/core/image_resizer.js\n\nconst MIN_IMAGE_DIM = 2048;\nconst MAX_IMAGE_DIM = 65537;\nconst MAX_ERROR = 128;\nclass ImageResizer {\n  constructor(imgData, isMask) {\n    this._imgData = imgData;\n    this._isMask = isMask;\n  }\n  static needsToBeResized(width, height) {\n    if (width <= this._goodSquareLength && height <= this._goodSquareLength) {\n      return false;\n    }\n    const {\n      MAX_DIM\n    } = this;\n    if (width > MAX_DIM || height > MAX_DIM) {\n      return true;\n    }\n    const area = width * height;\n    if (this._hasMaxArea) {\n      return area > this.MAX_AREA;\n    }\n    if (area < this._goodSquareLength ** 2) {\n      return false;\n    }\n    if (this._areGoodDims(width, height)) {\n      this._goodSquareLength = Math.max(this._goodSquareLength, Math.floor(Math.sqrt(width * height)));\n      return false;\n    }\n    this._goodSquareLength = this._guessMax(this._goodSquareLength, MAX_DIM, MAX_ERROR, 0);\n    const maxArea = this.MAX_AREA = this._goodSquareLength ** 2;\n    return area > maxArea;\n  }\n  static get MAX_DIM() {\n    return shadow(this, \"MAX_DIM\", this._guessMax(MIN_IMAGE_DIM, MAX_IMAGE_DIM, 0, 1));\n  }\n  static get MAX_AREA() {\n    this._hasMaxArea = true;\n    return shadow(this, \"MAX_AREA\", this._guessMax(ImageResizer._goodSquareLength, this.MAX_DIM, MAX_ERROR, 0) ** 2);\n  }\n  static set MAX_AREA(area) {\n    if (area >= 0) {\n      this._hasMaxArea = true;\n      shadow(this, \"MAX_AREA\", area);\n    }\n  }\n  static setMaxArea(area) {\n    if (!this._hasMaxArea) {\n      this.MAX_AREA = area >> 2;\n    }\n  }\n  static _areGoodDims(width, height) {\n    try {\n      const canvas = new OffscreenCanvas(width, height);\n      const ctx = canvas.getContext(\"2d\");\n      ctx.fillRect(0, 0, 1, 1);\n      const opacity = ctx.getImageData(0, 0, 1, 1).data[3];\n      canvas.width = canvas.height = 1;\n      return opacity !== 0;\n    } catch {\n      return false;\n    }\n  }\n  static _guessMax(start, end, tolerance, defaultHeight) {\n    while (start + tolerance + 1 < end) {\n      const middle = Math.floor((start + end) / 2);\n      const height = defaultHeight || middle;\n      if (this._areGoodDims(middle, height)) {\n        start = middle;\n      } else {\n        end = middle;\n      }\n    }\n    return start;\n  }\n  static async createImage(imgData, isMask = false) {\n    return new ImageResizer(imgData, isMask)._createImage();\n  }\n  async _createImage() {\n    const data = this._encodeBMP();\n    const blob = new Blob([data.buffer], {\n      type: \"image/bmp\"\n    });\n    const bitmapPromise = createImageBitmap(blob);\n    const {\n      MAX_AREA,\n      MAX_DIM\n    } = ImageResizer;\n    const {\n      _imgData: imgData\n    } = this;\n    const {\n      width,\n      height\n    } = imgData;\n    const minFactor = Math.max(width / MAX_DIM, height / MAX_DIM, Math.sqrt(width * height / MAX_AREA));\n    const firstFactor = Math.max(minFactor, 2);\n    const factor = Math.round(10 * (minFactor + 1.25)) / 10 / firstFactor;\n    const N = Math.floor(Math.log2(factor));\n    const steps = new Array(N + 2).fill(2);\n    steps[0] = firstFactor;\n    steps.splice(-1, 1, factor / (1 << N));\n    let newWidth = width;\n    let newHeight = height;\n    let bitmap = await bitmapPromise;\n    for (const step of steps) {\n      const prevWidth = newWidth;\n      const prevHeight = newHeight;\n      newWidth = Math.floor(newWidth / step) - 1;\n      newHeight = Math.floor(newHeight / step) - 1;\n      const canvas = new OffscreenCanvas(newWidth, newHeight);\n      const ctx = canvas.getContext(\"2d\");\n      ctx.drawImage(bitmap, 0, 0, prevWidth, prevHeight, 0, 0, newWidth, newHeight);\n      bitmap = canvas.transferToImageBitmap();\n    }\n    imgData.data = null;\n    imgData.bitmap = bitmap;\n    imgData.width = newWidth;\n    imgData.height = newHeight;\n    return imgData;\n  }\n  _encodeBMP() {\n    const {\n      width,\n      height,\n      kind\n    } = this._imgData;\n    let data = this._imgData.data;\n    let bitPerPixel;\n    let colorTable = new Uint8Array(0);\n    let maskTable = colorTable;\n    let compression = 0;\n    switch (kind) {\n      case ImageKind.GRAYSCALE_1BPP:\n        {\n          bitPerPixel = 1;\n          colorTable = new Uint8Array(this._isMask ? [255, 255, 255, 255, 0, 0, 0, 0] : [0, 0, 0, 0, 255, 255, 255, 255]);\n          const rowLen = width + 7 >> 3;\n          const rowSize = rowLen + 3 & -4;\n          if (rowLen !== rowSize) {\n            const newData = new Uint8Array(rowSize * height);\n            let k = 0;\n            for (let i = 0, ii = height * rowLen; i < ii; i += rowLen, k += rowSize) {\n              newData.set(data.subarray(i, i + rowLen), k);\n            }\n            data = newData;\n          }\n          break;\n        }\n      case ImageKind.RGB_24BPP:\n        {\n          bitPerPixel = 24;\n          if (width & 3) {\n            const rowLen = 3 * width;\n            const rowSize = rowLen + 3 & -4;\n            const extraLen = rowSize - rowLen;\n            const newData = new Uint8Array(rowSize * height);\n            let k = 0;\n            for (let i = 0, ii = height * rowLen; i < ii; i += rowLen) {\n              const row = data.subarray(i, i + rowLen);\n              for (let j = 0; j < rowLen; j += 3) {\n                newData[k++] = row[j + 2];\n                newData[k++] = row[j + 1];\n                newData[k++] = row[j];\n              }\n              k += extraLen;\n            }\n            data = newData;\n          } else {\n            for (let i = 0, ii = data.length; i < ii; i += 3) {\n              const tmp = data[i];\n              data[i] = data[i + 2];\n              data[i + 2] = tmp;\n            }\n          }\n          break;\n        }\n      case ImageKind.RGBA_32BPP:\n        bitPerPixel = 32;\n        compression = 3;\n        maskTable = new Uint8Array(4 + 4 + 4 + 4 + 52);\n        const view = new DataView(maskTable.buffer);\n        if (FeatureTest.isLittleEndian) {\n          view.setUint32(0, 0x000000ff, true);\n          view.setUint32(4, 0x0000ff00, true);\n          view.setUint32(8, 0x00ff0000, true);\n          view.setUint32(12, 0xff000000, true);\n        } else {\n          view.setUint32(0, 0xff000000, true);\n          view.setUint32(4, 0x00ff0000, true);\n          view.setUint32(8, 0x0000ff00, true);\n          view.setUint32(12, 0x000000ff, true);\n        }\n        break;\n      default:\n        throw new Error(\"invalid format\");\n    }\n    let i = 0;\n    const headerLength = 40 + maskTable.length;\n    const fileLength = 14 + headerLength + colorTable.length + data.length;\n    const bmpData = new Uint8Array(fileLength);\n    const view = new DataView(bmpData.buffer);\n    view.setUint16(i, 0x4d42, true);\n    i += 2;\n    view.setUint32(i, fileLength, true);\n    i += 4;\n    view.setUint32(i, 0, true);\n    i += 4;\n    view.setUint32(i, 14 + headerLength + colorTable.length, true);\n    i += 4;\n    view.setUint32(i, headerLength, true);\n    i += 4;\n    view.setInt32(i, width, true);\n    i += 4;\n    view.setInt32(i, -height, true);\n    i += 4;\n    view.setUint16(i, 1, true);\n    i += 2;\n    view.setUint16(i, bitPerPixel, true);\n    i += 2;\n    view.setUint32(i, compression, true);\n    i += 4;\n    view.setUint32(i, 0, true);\n    i += 4;\n    view.setInt32(i, 0, true);\n    i += 4;\n    view.setInt32(i, 0, true);\n    i += 4;\n    view.setUint32(i, colorTable.length / 4, true);\n    i += 4;\n    view.setUint32(i, 0, true);\n    i += 4;\n    bmpData.set(maskTable, i);\n    i += maskTable.length;\n    bmpData.set(colorTable, i);\n    i += colorTable.length;\n    bmpData.set(data, i);\n    return bmpData;\n  }\n}\nImageResizer._goodSquareLength = MIN_IMAGE_DIM;\n\n;// ./src/shared/murmurhash3.js\nconst SEED = 0xc3d2e1f0;\nconst MASK_HIGH = 0xffff0000;\nconst MASK_LOW = 0xffff;\nclass MurmurHash3_64 {\n  constructor(seed) {\n    this.h1 = seed ? seed & 0xffffffff : SEED;\n    this.h2 = seed ? seed & 0xffffffff : SEED;\n  }\n  update(input) {\n    let data, length;\n    if (typeof input === \"string\") {\n      data = new Uint8Array(input.length * 2);\n      length = 0;\n      for (let i = 0, ii = input.length; i < ii; i++) {\n        const code = input.charCodeAt(i);\n        if (code <= 0xff) {\n          data[length++] = code;\n        } else {\n          data[length++] = code >>> 8;\n          data[length++] = code & 0xff;\n        }\n      }\n    } else if (ArrayBuffer.isView(input)) {\n      data = input.slice();\n      length = data.byteLength;\n    } else {\n      throw new Error(\"Invalid data format, must be a string or TypedArray.\");\n    }\n    const blockCounts = length >> 2;\n    const tailLength = length - blockCounts * 4;\n    const dataUint32 = new Uint32Array(data.buffer, 0, blockCounts);\n    let k1 = 0,\n      k2 = 0;\n    let h1 = this.h1,\n      h2 = this.h2;\n    const C1 = 0xcc9e2d51,\n      C2 = 0x1b873593;\n    const C1_LOW = C1 & MASK_LOW,\n      C2_LOW = C2 & MASK_LOW;\n    for (let i = 0; i < blockCounts; i++) {\n      if (i & 1) {\n        k1 = dataUint32[i];\n        k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW;\n        k1 = k1 << 15 | k1 >>> 17;\n        k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW;\n        h1 ^= k1;\n        h1 = h1 << 13 | h1 >>> 19;\n        h1 = h1 * 5 + 0xe6546b64;\n      } else {\n        k2 = dataUint32[i];\n        k2 = k2 * C1 & MASK_HIGH | k2 * C1_LOW & MASK_LOW;\n        k2 = k2 << 15 | k2 >>> 17;\n        k2 = k2 * C2 & MASK_HIGH | k2 * C2_LOW & MASK_LOW;\n        h2 ^= k2;\n        h2 = h2 << 13 | h2 >>> 19;\n        h2 = h2 * 5 + 0xe6546b64;\n      }\n    }\n    k1 = 0;\n    switch (tailLength) {\n      case 3:\n        k1 ^= data[blockCounts * 4 + 2] << 16;\n      case 2:\n        k1 ^= data[blockCounts * 4 + 1] << 8;\n      case 1:\n        k1 ^= data[blockCounts * 4];\n        k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW;\n        k1 = k1 << 15 | k1 >>> 17;\n        k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW;\n        if (blockCounts & 1) {\n          h1 ^= k1;\n        } else {\n          h2 ^= k1;\n        }\n    }\n    this.h1 = h1;\n    this.h2 = h2;\n  }\n  hexdigest() {\n    let h1 = this.h1,\n      h2 = this.h2;\n    h1 ^= h2 >>> 1;\n    h1 = h1 * 0xed558ccd & MASK_HIGH | h1 * 0x8ccd & MASK_LOW;\n    h2 = h2 * 0xff51afd7 & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xafd7ed55 & MASK_HIGH) >>> 16;\n    h1 ^= h2 >>> 1;\n    h1 = h1 * 0x1a85ec53 & MASK_HIGH | h1 * 0xec53 & MASK_LOW;\n    h2 = h2 * 0xc4ceb9fe & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xb9fe1a85 & MASK_HIGH) >>> 16;\n    h1 ^= h2 >>> 1;\n    return (h1 >>> 0).toString(16).padStart(8, \"0\") + (h2 >>> 0).toString(16).padStart(8, \"0\");\n  }\n}\n\n;// ./src/core/operator_list.js\n\nfunction addState(parentState, pattern, checkFn, iterateFn, processFn) {\n  let state = parentState;\n  for (let i = 0, ii = pattern.length - 1; i < ii; i++) {\n    const item = pattern[i];\n    state = state[item] ||= [];\n  }\n  state[pattern.at(-1)] = {\n    checkFn,\n    iterateFn,\n    processFn\n  };\n}\nconst InitialState = [];\naddState(InitialState, [OPS.save, OPS.transform, OPS.paintInlineImageXObject, OPS.restore], null, function iterateInlineImageGroup(context, i) {\n  const fnArray = context.fnArray;\n  const iFirstSave = context.iCurr - 3;\n  const pos = (i - iFirstSave) % 4;\n  switch (pos) {\n    case 0:\n      return fnArray[i] === OPS.save;\n    case 1:\n      return fnArray[i] === OPS.transform;\n    case 2:\n      return fnArray[i] === OPS.paintInlineImageXObject;\n    case 3:\n      return fnArray[i] === OPS.restore;\n  }\n  throw new Error(`iterateInlineImageGroup - invalid pos: ${pos}`);\n}, function foundInlineImageGroup(context, i) {\n  const MIN_IMAGES_IN_INLINE_IMAGES_BLOCK = 10;\n  const MAX_IMAGES_IN_INLINE_IMAGES_BLOCK = 200;\n  const MAX_WIDTH = 1000;\n  const IMAGE_PADDING = 1;\n  const fnArray = context.fnArray,\n    argsArray = context.argsArray;\n  const curr = context.iCurr;\n  const iFirstSave = curr - 3;\n  const iFirstTransform = curr - 2;\n  const iFirstPIIXO = curr - 1;\n  const count = Math.min(Math.floor((i - iFirstSave) / 4), MAX_IMAGES_IN_INLINE_IMAGES_BLOCK);\n  if (count < MIN_IMAGES_IN_INLINE_IMAGES_BLOCK) {\n    return i - (i - iFirstSave) % 4;\n  }\n  let maxX = 0;\n  const map = [];\n  let maxLineHeight = 0;\n  let currentX = IMAGE_PADDING,\n    currentY = IMAGE_PADDING;\n  for (let q = 0; q < count; q++) {\n    const transform = argsArray[iFirstTransform + (q << 2)];\n    const img = argsArray[iFirstPIIXO + (q << 2)][0];\n    if (currentX + img.width > MAX_WIDTH) {\n      maxX = Math.max(maxX, currentX);\n      currentY += maxLineHeight + 2 * IMAGE_PADDING;\n      currentX = 0;\n      maxLineHeight = 0;\n    }\n    map.push({\n      transform,\n      x: currentX,\n      y: currentY,\n      w: img.width,\n      h: img.height\n    });\n    currentX += img.width + 2 * IMAGE_PADDING;\n    maxLineHeight = Math.max(maxLineHeight, img.height);\n  }\n  const imgWidth = Math.max(maxX, currentX) + IMAGE_PADDING;\n  const imgHeight = currentY + maxLineHeight + IMAGE_PADDING;\n  const imgData = new Uint8Array(imgWidth * imgHeight * 4);\n  const imgRowSize = imgWidth << 2;\n  for (let q = 0; q < count; q++) {\n    const data = argsArray[iFirstPIIXO + (q << 2)][0].data;\n    const rowSize = map[q].w << 2;\n    let dataOffset = 0;\n    let offset = map[q].x + map[q].y * imgWidth << 2;\n    imgData.set(data.subarray(0, rowSize), offset - imgRowSize);\n    for (let k = 0, kk = map[q].h; k < kk; k++) {\n      imgData.set(data.subarray(dataOffset, dataOffset + rowSize), offset);\n      dataOffset += rowSize;\n      offset += imgRowSize;\n    }\n    imgData.set(data.subarray(dataOffset - rowSize, dataOffset), offset);\n    while (offset >= 0) {\n      data[offset - 4] = data[offset];\n      data[offset - 3] = data[offset + 1];\n      data[offset - 2] = data[offset + 2];\n      data[offset - 1] = data[offset + 3];\n      data[offset + rowSize] = data[offset + rowSize - 4];\n      data[offset + rowSize + 1] = data[offset + rowSize - 3];\n      data[offset + rowSize + 2] = data[offset + rowSize - 2];\n      data[offset + rowSize + 3] = data[offset + rowSize - 1];\n      offset -= imgRowSize;\n    }\n  }\n  const img = {\n    width: imgWidth,\n    height: imgHeight\n  };\n  if (context.isOffscreenCanvasSupported) {\n    const canvas = new OffscreenCanvas(imgWidth, imgHeight);\n    const ctx = canvas.getContext(\"2d\");\n    ctx.putImageData(new ImageData(new Uint8ClampedArray(imgData.buffer), imgWidth, imgHeight), 0, 0);\n    img.bitmap = canvas.transferToImageBitmap();\n    img.data = null;\n  } else {\n    img.kind = ImageKind.RGBA_32BPP;\n    img.data = imgData;\n  }\n  fnArray.splice(iFirstSave, count * 4, OPS.paintInlineImageXObjectGroup);\n  argsArray.splice(iFirstSave, count * 4, [img, map]);\n  return iFirstSave + 1;\n});\naddState(InitialState, [OPS.save, OPS.transform, OPS.paintImageMaskXObject, OPS.restore], null, function iterateImageMaskGroup(context, i) {\n  const fnArray = context.fnArray;\n  const iFirstSave = context.iCurr - 3;\n  const pos = (i - iFirstSave) % 4;\n  switch (pos) {\n    case 0:\n      return fnArray[i] === OPS.save;\n    case 1:\n      return fnArray[i] === OPS.transform;\n    case 2:\n      return fnArray[i] === OPS.paintImageMaskXObject;\n    case 3:\n      return fnArray[i] === OPS.restore;\n  }\n  throw new Error(`iterateImageMaskGroup - invalid pos: ${pos}`);\n}, function foundImageMaskGroup(context, i) {\n  const MIN_IMAGES_IN_MASKS_BLOCK = 10;\n  const MAX_IMAGES_IN_MASKS_BLOCK = 100;\n  const MAX_SAME_IMAGES_IN_MASKS_BLOCK = 1000;\n  const fnArray = context.fnArray,\n    argsArray = context.argsArray;\n  const curr = context.iCurr;\n  const iFirstSave = curr - 3;\n  const iFirstTransform = curr - 2;\n  const iFirstPIMXO = curr - 1;\n  let count = Math.floor((i - iFirstSave) / 4);\n  if (count < MIN_IMAGES_IN_MASKS_BLOCK) {\n    return i - (i - iFirstSave) % 4;\n  }\n  let isSameImage = false;\n  let iTransform, transformArgs;\n  const firstPIMXOArg0 = argsArray[iFirstPIMXO][0];\n  const firstTransformArg0 = argsArray[iFirstTransform][0],\n    firstTransformArg1 = argsArray[iFirstTransform][1],\n    firstTransformArg2 = argsArray[iFirstTransform][2],\n    firstTransformArg3 = argsArray[iFirstTransform][3];\n  if (firstTransformArg1 === firstTransformArg2) {\n    isSameImage = true;\n    iTransform = iFirstTransform + 4;\n    let iPIMXO = iFirstPIMXO + 4;\n    for (let q = 1; q < count; q++, iTransform += 4, iPIMXO += 4) {\n      transformArgs = argsArray[iTransform];\n      if (argsArray[iPIMXO][0] !== firstPIMXOArg0 || transformArgs[0] !== firstTransformArg0 || transformArgs[1] !== firstTransformArg1 || transformArgs[2] !== firstTransformArg2 || transformArgs[3] !== firstTransformArg3) {\n        if (q < MIN_IMAGES_IN_MASKS_BLOCK) {\n          isSameImage = false;\n        } else {\n          count = q;\n        }\n        break;\n      }\n    }\n  }\n  if (isSameImage) {\n    count = Math.min(count, MAX_SAME_IMAGES_IN_MASKS_BLOCK);\n    const positions = new Float32Array(count * 2);\n    iTransform = iFirstTransform;\n    for (let q = 0; q < count; q++, iTransform += 4) {\n      transformArgs = argsArray[iTransform];\n      positions[q << 1] = transformArgs[4];\n      positions[(q << 1) + 1] = transformArgs[5];\n    }\n    fnArray.splice(iFirstSave, count * 4, OPS.paintImageMaskXObjectRepeat);\n    argsArray.splice(iFirstSave, count * 4, [firstPIMXOArg0, firstTransformArg0, firstTransformArg1, firstTransformArg2, firstTransformArg3, positions]);\n  } else {\n    count = Math.min(count, MAX_IMAGES_IN_MASKS_BLOCK);\n    const images = [];\n    for (let q = 0; q < count; q++) {\n      transformArgs = argsArray[iFirstTransform + (q << 2)];\n      const maskParams = argsArray[iFirstPIMXO + (q << 2)][0];\n      images.push({\n        data: maskParams.data,\n        width: maskParams.width,\n        height: maskParams.height,\n        interpolate: maskParams.interpolate,\n        count: maskParams.count,\n        transform: transformArgs\n      });\n    }\n    fnArray.splice(iFirstSave, count * 4, OPS.paintImageMaskXObjectGroup);\n    argsArray.splice(iFirstSave, count * 4, [images]);\n  }\n  return iFirstSave + 1;\n});\naddState(InitialState, [OPS.save, OPS.transform, OPS.paintImageXObject, OPS.restore], function (context) {\n  const argsArray = context.argsArray;\n  const iFirstTransform = context.iCurr - 2;\n  return argsArray[iFirstTransform][1] === 0 && argsArray[iFirstTransform][2] === 0;\n}, function iterateImageGroup(context, i) {\n  const fnArray = context.fnArray,\n    argsArray = context.argsArray;\n  const iFirstSave = context.iCurr - 3;\n  const pos = (i - iFirstSave) % 4;\n  switch (pos) {\n    case 0:\n      return fnArray[i] === OPS.save;\n    case 1:\n      if (fnArray[i] !== OPS.transform) {\n        return false;\n      }\n      const iFirstTransform = context.iCurr - 2;\n      const firstTransformArg0 = argsArray[iFirstTransform][0];\n      const firstTransformArg3 = argsArray[iFirstTransform][3];\n      if (argsArray[i][0] !== firstTransformArg0 || argsArray[i][1] !== 0 || argsArray[i][2] !== 0 || argsArray[i][3] !== firstTransformArg3) {\n        return false;\n      }\n      return true;\n    case 2:\n      if (fnArray[i] !== OPS.paintImageXObject) {\n        return false;\n      }\n      const iFirstPIXO = context.iCurr - 1;\n      const firstPIXOArg0 = argsArray[iFirstPIXO][0];\n      if (argsArray[i][0] !== firstPIXOArg0) {\n        return false;\n      }\n      return true;\n    case 3:\n      return fnArray[i] === OPS.restore;\n  }\n  throw new Error(`iterateImageGroup - invalid pos: ${pos}`);\n}, function (context, i) {\n  const MIN_IMAGES_IN_BLOCK = 3;\n  const MAX_IMAGES_IN_BLOCK = 1000;\n  const fnArray = context.fnArray,\n    argsArray = context.argsArray;\n  const curr = context.iCurr;\n  const iFirstSave = curr - 3;\n  const iFirstTransform = curr - 2;\n  const iFirstPIXO = curr - 1;\n  const firstPIXOArg0 = argsArray[iFirstPIXO][0];\n  const firstTransformArg0 = argsArray[iFirstTransform][0];\n  const firstTransformArg3 = argsArray[iFirstTransform][3];\n  const count = Math.min(Math.floor((i - iFirstSave) / 4), MAX_IMAGES_IN_BLOCK);\n  if (count < MIN_IMAGES_IN_BLOCK) {\n    return i - (i - iFirstSave) % 4;\n  }\n  const positions = new Float32Array(count * 2);\n  let iTransform = iFirstTransform;\n  for (let q = 0; q < count; q++, iTransform += 4) {\n    const transformArgs = argsArray[iTransform];\n    positions[q << 1] = transformArgs[4];\n    positions[(q << 1) + 1] = transformArgs[5];\n  }\n  const args = [firstPIXOArg0, firstTransformArg0, firstTransformArg3, positions];\n  fnArray.splice(iFirstSave, count * 4, OPS.paintImageXObjectRepeat);\n  argsArray.splice(iFirstSave, count * 4, args);\n  return iFirstSave + 1;\n});\naddState(InitialState, [OPS.beginText, OPS.setFont, OPS.setTextMatrix, OPS.showText, OPS.endText], null, function iterateShowTextGroup(context, i) {\n  const fnArray = context.fnArray,\n    argsArray = context.argsArray;\n  const iFirstSave = context.iCurr - 4;\n  const pos = (i - iFirstSave) % 5;\n  switch (pos) {\n    case 0:\n      return fnArray[i] === OPS.beginText;\n    case 1:\n      return fnArray[i] === OPS.setFont;\n    case 2:\n      return fnArray[i] === OPS.setTextMatrix;\n    case 3:\n      if (fnArray[i] !== OPS.showText) {\n        return false;\n      }\n      const iFirstSetFont = context.iCurr - 3;\n      const firstSetFontArg0 = argsArray[iFirstSetFont][0];\n      const firstSetFontArg1 = argsArray[iFirstSetFont][1];\n      if (argsArray[i][0] !== firstSetFontArg0 || argsArray[i][1] !== firstSetFontArg1) {\n        return false;\n      }\n      return true;\n    case 4:\n      return fnArray[i] === OPS.endText;\n  }\n  throw new Error(`iterateShowTextGroup - invalid pos: ${pos}`);\n}, function (context, i) {\n  const MIN_CHARS_IN_BLOCK = 3;\n  const MAX_CHARS_IN_BLOCK = 1000;\n  const fnArray = context.fnArray,\n    argsArray = context.argsArray;\n  const curr = context.iCurr;\n  const iFirstBeginText = curr - 4;\n  const iFirstSetFont = curr - 3;\n  const iFirstSetTextMatrix = curr - 2;\n  const iFirstShowText = curr - 1;\n  const iFirstEndText = curr;\n  const firstSetFontArg0 = argsArray[iFirstSetFont][0];\n  const firstSetFontArg1 = argsArray[iFirstSetFont][1];\n  let count = Math.min(Math.floor((i - iFirstBeginText) / 5), MAX_CHARS_IN_BLOCK);\n  if (count < MIN_CHARS_IN_BLOCK) {\n    return i - (i - iFirstBeginText) % 5;\n  }\n  let iFirst = iFirstBeginText;\n  if (iFirstBeginText >= 4 && fnArray[iFirstBeginText - 4] === fnArray[iFirstSetFont] && fnArray[iFirstBeginText - 3] === fnArray[iFirstSetTextMatrix] && fnArray[iFirstBeginText - 2] === fnArray[iFirstShowText] && fnArray[iFirstBeginText - 1] === fnArray[iFirstEndText] && argsArray[iFirstBeginText - 4][0] === firstSetFontArg0 && argsArray[iFirstBeginText - 4][1] === firstSetFontArg1) {\n    count++;\n    iFirst -= 5;\n  }\n  let iEndText = iFirst + 4;\n  for (let q = 1; q < count; q++) {\n    fnArray.splice(iEndText, 3);\n    argsArray.splice(iEndText, 3);\n    iEndText += 2;\n  }\n  return iEndText + 1;\n});\nclass NullOptimizer {\n  constructor(queue) {\n    this.queue = queue;\n  }\n  _optimize() {}\n  push(fn, args) {\n    this.queue.fnArray.push(fn);\n    this.queue.argsArray.push(args);\n    this._optimize();\n  }\n  flush() {}\n  reset() {}\n}\nclass QueueOptimizer extends NullOptimizer {\n  constructor(queue) {\n    super(queue);\n    this.state = null;\n    this.context = {\n      iCurr: 0,\n      fnArray: queue.fnArray,\n      argsArray: queue.argsArray,\n      isOffscreenCanvasSupported: false\n    };\n    this.match = null;\n    this.lastProcessed = 0;\n  }\n  set isOffscreenCanvasSupported(value) {\n    this.context.isOffscreenCanvasSupported = value;\n  }\n  _optimize() {\n    const fnArray = this.queue.fnArray;\n    let i = this.lastProcessed,\n      ii = fnArray.length;\n    let state = this.state;\n    let match = this.match;\n    if (!state && !match && i + 1 === ii && !InitialState[fnArray[i]]) {\n      this.lastProcessed = ii;\n      return;\n    }\n    const context = this.context;\n    while (i < ii) {\n      if (match) {\n        const iterate = (0, match.iterateFn)(context, i);\n        if (iterate) {\n          i++;\n          continue;\n        }\n        i = (0, match.processFn)(context, i + 1);\n        ii = fnArray.length;\n        match = null;\n        state = null;\n        if (i >= ii) {\n          break;\n        }\n      }\n      state = (state || InitialState)[fnArray[i]];\n      if (!state || Array.isArray(state)) {\n        i++;\n        continue;\n      }\n      context.iCurr = i;\n      i++;\n      if (state.checkFn && !(0, state.checkFn)(context)) {\n        state = null;\n        continue;\n      }\n      match = state;\n      state = null;\n    }\n    this.state = state;\n    this.match = match;\n    this.lastProcessed = i;\n  }\n  flush() {\n    while (this.match) {\n      const length = this.queue.fnArray.length;\n      this.lastProcessed = (0, this.match.processFn)(this.context, length);\n      this.match = null;\n      this.state = null;\n      this._optimize();\n    }\n  }\n  reset() {\n    this.state = null;\n    this.match = null;\n    this.lastProcessed = 0;\n  }\n}\nclass OperatorList {\n  static CHUNK_SIZE = 1000;\n  static CHUNK_SIZE_ABOUT = this.CHUNK_SIZE - 5;\n  constructor(intent = 0, streamSink) {\n    this._streamSink = streamSink;\n    this.fnArray = [];\n    this.argsArray = [];\n    this.optimizer = streamSink && !(intent & RenderingIntentFlag.OPLIST) ? new QueueOptimizer(this) : new NullOptimizer(this);\n    this.dependencies = new Set();\n    this._totalLength = 0;\n    this.weight = 0;\n    this._resolved = streamSink ? null : Promise.resolve();\n  }\n  set isOffscreenCanvasSupported(value) {\n    this.optimizer.isOffscreenCanvasSupported = value;\n  }\n  get length() {\n    return this.argsArray.length;\n  }\n  get ready() {\n    return this._resolved || this._streamSink.ready;\n  }\n  get totalLength() {\n    return this._totalLength + this.length;\n  }\n  addOp(fn, args) {\n    this.optimizer.push(fn, args);\n    this.weight++;\n    if (this._streamSink) {\n      if (this.weight >= OperatorList.CHUNK_SIZE) {\n        this.flush();\n      } else if (this.weight >= OperatorList.CHUNK_SIZE_ABOUT && (fn === OPS.restore || fn === OPS.endText)) {\n        this.flush();\n      }\n    }\n  }\n  addImageOps(fn, args, optionalContent) {\n    if (optionalContent !== undefined) {\n      this.addOp(OPS.beginMarkedContentProps, [\"OC\", optionalContent]);\n    }\n    this.addOp(fn, args);\n    if (optionalContent !== undefined) {\n      this.addOp(OPS.endMarkedContent, []);\n    }\n  }\n  addDependency(dependency) {\n    if (this.dependencies.has(dependency)) {\n      return;\n    }\n    this.dependencies.add(dependency);\n    this.addOp(OPS.dependency, [dependency]);\n  }\n  addDependencies(dependencies) {\n    for (const dependency of dependencies) {\n      this.addDependency(dependency);\n    }\n  }\n  addOpList(opList) {\n    if (!(opList instanceof OperatorList)) {\n      warn('addOpList - ignoring invalid \"opList\" parameter.');\n      return;\n    }\n    for (const dependency of opList.dependencies) {\n      this.dependencies.add(dependency);\n    }\n    for (let i = 0, ii = opList.length; i < ii; i++) {\n      this.addOp(opList.fnArray[i], opList.argsArray[i]);\n    }\n  }\n  getIR() {\n    return {\n      fnArray: this.fnArray,\n      argsArray: this.argsArray,\n      length: this.length\n    };\n  }\n  get _transfers() {\n    const transfers = [];\n    const {\n      fnArray,\n      argsArray,\n      length\n    } = this;\n    for (let i = 0; i < length; i++) {\n      switch (fnArray[i]) {\n        case OPS.paintInlineImageXObject:\n        case OPS.paintInlineImageXObjectGroup:\n        case OPS.paintImageMaskXObject:\n          const arg = argsArray[i][0];\n          if (!arg.cached && arg.data?.buffer instanceof ArrayBuffer) {\n            transfers.push(arg.data.buffer);\n          }\n          break;\n      }\n    }\n    return transfers;\n  }\n  flush(lastChunk = false, separateAnnots = null) {\n    this.optimizer.flush();\n    const length = this.length;\n    this._totalLength += length;\n    this._streamSink.enqueue({\n      fnArray: this.fnArray,\n      argsArray: this.argsArray,\n      lastChunk,\n      separateAnnots,\n      length\n    }, 1, this._transfers);\n    this.dependencies.clear();\n    this.fnArray.length = 0;\n    this.argsArray.length = 0;\n    this.weight = 0;\n    this.optimizer.reset();\n  }\n}\n\n;// ./src/core/image.js\n\n\n\n\n\n\n\n\n\nfunction decodeAndClamp(value, addend, coefficient, max) {\n  value = addend + value * coefficient;\n  if (value < 0) {\n    value = 0;\n  } else if (value > max) {\n    value = max;\n  }\n  return value;\n}\nfunction resizeImageMask(src, bpc, w1, h1, w2, h2) {\n  const length = w2 * h2;\n  let dest;\n  if (bpc <= 8) {\n    dest = new Uint8Array(length);\n  } else if (bpc <= 16) {\n    dest = new Uint16Array(length);\n  } else {\n    dest = new Uint32Array(length);\n  }\n  const xRatio = w1 / w2;\n  const yRatio = h1 / h2;\n  let i,\n    j,\n    py,\n    newIndex = 0,\n    oldIndex;\n  const xScaled = new Uint16Array(w2);\n  const w1Scanline = w1;\n  for (i = 0; i < w2; i++) {\n    xScaled[i] = Math.floor(i * xRatio);\n  }\n  for (i = 0; i < h2; i++) {\n    py = Math.floor(i * yRatio) * w1Scanline;\n    for (j = 0; j < w2; j++) {\n      oldIndex = py + xScaled[j];\n      dest[newIndex++] = src[oldIndex];\n    }\n  }\n  return dest;\n}\nclass PDFImage {\n  constructor({\n    xref,\n    res,\n    image,\n    isInline = false,\n    smask = null,\n    mask = null,\n    isMask = false,\n    pdfFunctionFactory,\n    localColorSpaceCache\n  }) {\n    this.image = image;\n    let jpxDecode = false;\n    const dict = image.dict;\n    const filter = dict.get(\"F\", \"Filter\");\n    let filterName;\n    if (filter instanceof Name) {\n      filterName = filter.name;\n    } else if (Array.isArray(filter)) {\n      const filterZero = xref.fetchIfRef(filter[0]);\n      if (filterZero instanceof Name) {\n        filterName = filterZero.name;\n      }\n    }\n    switch (filterName) {\n      case \"JPXDecode\":\n        ({\n          width: image.width,\n          height: image.height,\n          componentsCount: image.numComps,\n          bitsPerComponent: image.bitsPerComponent\n        } = JpxImage.parseImageProperties(image.stream));\n        image.stream.reset();\n        jpxDecode = true;\n        break;\n      case \"JBIG2Decode\":\n        image.bitsPerComponent = 1;\n        image.numComps = 1;\n        break;\n    }\n    let width = dict.get(\"W\", \"Width\");\n    let height = dict.get(\"H\", \"Height\");\n    if (Number.isInteger(image.width) && image.width > 0 && Number.isInteger(image.height) && image.height > 0 && (image.width !== width || image.height !== height)) {\n      warn(\"PDFImage - using the Width/Height of the image data, \" + \"rather than the image dictionary.\");\n      width = image.width;\n      height = image.height;\n    }\n    if (width < 1 || height < 1) {\n      throw new FormatError(`Invalid image width: ${width} or height: ${height}`);\n    }\n    this.width = width;\n    this.height = height;\n    this.interpolate = dict.get(\"I\", \"Interpolate\");\n    this.imageMask = dict.get(\"IM\", \"ImageMask\") || false;\n    this.matte = dict.get(\"Matte\") || false;\n    let bitsPerComponent = image.bitsPerComponent;\n    if (!bitsPerComponent) {\n      bitsPerComponent = dict.get(\"BPC\", \"BitsPerComponent\");\n      if (!bitsPerComponent) {\n        if (this.imageMask) {\n          bitsPerComponent = 1;\n        } else {\n          throw new FormatError(`Bits per component missing in image: ${this.imageMask}`);\n        }\n      }\n    }\n    this.bpc = bitsPerComponent;\n    if (!this.imageMask) {\n      let colorSpace = dict.getRaw(\"CS\") || dict.getRaw(\"ColorSpace\");\n      if (!colorSpace) {\n        info(\"JPX images (which do not require color spaces)\");\n        switch (image.numComps) {\n          case 1:\n            colorSpace = Name.get(\"DeviceGray\");\n            break;\n          case 3:\n            colorSpace = Name.get(\"DeviceRGB\");\n            break;\n          case 4:\n            colorSpace = Name.get(\"DeviceCMYK\");\n            break;\n          default:\n            throw new Error(`JPX images with ${image.numComps} color components not supported.`);\n        }\n      }\n      this.colorSpace = ColorSpace.parse({\n        cs: colorSpace,\n        xref,\n        resources: isInline ? res : null,\n        pdfFunctionFactory,\n        localColorSpaceCache\n      });\n      this.numComps = this.colorSpace.numComps;\n      this.ignoreColorSpace = jpxDecode && this.colorSpace.name === \"Indexed\";\n    }\n    this.decode = dict.getArray(\"D\", \"Decode\");\n    this.needsDecode = false;\n    if (this.decode && (this.colorSpace && !this.colorSpace.isDefaultDecode(this.decode, bitsPerComponent) || isMask && !ColorSpace.isDefaultDecode(this.decode, 1))) {\n      this.needsDecode = true;\n      const max = (1 << bitsPerComponent) - 1;\n      this.decodeCoefficients = [];\n      this.decodeAddends = [];\n      const isIndexed = this.colorSpace?.name === \"Indexed\";\n      for (let i = 0, j = 0; i < this.decode.length; i += 2, ++j) {\n        const dmin = this.decode[i];\n        const dmax = this.decode[i + 1];\n        this.decodeCoefficients[j] = isIndexed ? (dmax - dmin) / max : dmax - dmin;\n        this.decodeAddends[j] = isIndexed ? dmin : max * dmin;\n      }\n    }\n    if (smask) {\n      this.smask = new PDFImage({\n        xref,\n        res,\n        image: smask,\n        isInline,\n        pdfFunctionFactory,\n        localColorSpaceCache\n      });\n    } else if (mask) {\n      if (mask instanceof BaseStream) {\n        const maskDict = mask.dict,\n          imageMask = maskDict.get(\"IM\", \"ImageMask\");\n        if (!imageMask) {\n          warn(\"Ignoring /Mask in image without /ImageMask.\");\n        } else {\n          this.mask = new PDFImage({\n            xref,\n            res,\n            image: mask,\n            isInline,\n            isMask: true,\n            pdfFunctionFactory,\n            localColorSpaceCache\n          });\n        }\n      } else {\n        this.mask = mask;\n      }\n    }\n  }\n  static async buildImage({\n    xref,\n    res,\n    image,\n    isInline = false,\n    pdfFunctionFactory,\n    localColorSpaceCache\n  }) {\n    const imageData = image;\n    let smaskData = null;\n    let maskData = null;\n    const smask = image.dict.get(\"SMask\");\n    const mask = image.dict.get(\"Mask\");\n    if (smask) {\n      if (smask instanceof BaseStream) {\n        smaskData = smask;\n      } else {\n        warn(\"Unsupported /SMask format.\");\n      }\n    } else if (mask) {\n      if (mask instanceof BaseStream || Array.isArray(mask)) {\n        maskData = mask;\n      } else {\n        warn(\"Unsupported /Mask format.\");\n      }\n    }\n    return new PDFImage({\n      xref,\n      res,\n      image: imageData,\n      isInline,\n      smask: smaskData,\n      mask: maskData,\n      pdfFunctionFactory,\n      localColorSpaceCache\n    });\n  }\n  static createRawMask({\n    imgArray,\n    width,\n    height,\n    imageIsFromDecodeStream,\n    inverseDecode,\n    interpolate\n  }) {\n    const computedLength = (width + 7 >> 3) * height;\n    const actualLength = imgArray.byteLength;\n    const haveFullData = computedLength === actualLength;\n    let data, i;\n    if (imageIsFromDecodeStream && (!inverseDecode || haveFullData)) {\n      data = imgArray;\n    } else if (!inverseDecode) {\n      data = new Uint8Array(imgArray);\n    } else {\n      data = new Uint8Array(computedLength);\n      data.set(imgArray);\n      data.fill(0xff, actualLength);\n    }\n    if (inverseDecode) {\n      for (i = 0; i < actualLength; i++) {\n        data[i] ^= 0xff;\n      }\n    }\n    return {\n      data,\n      width,\n      height,\n      interpolate\n    };\n  }\n  static async createMask({\n    imgArray,\n    width,\n    height,\n    imageIsFromDecodeStream,\n    inverseDecode,\n    interpolate,\n    isOffscreenCanvasSupported = false\n  }) {\n    const isSingleOpaquePixel = width === 1 && height === 1 && inverseDecode === (imgArray.length === 0 || !!(imgArray[0] & 128));\n    if (isSingleOpaquePixel) {\n      return {\n        isSingleOpaquePixel\n      };\n    }\n    if (isOffscreenCanvasSupported) {\n      if (ImageResizer.needsToBeResized(width, height)) {\n        const data = new Uint8ClampedArray(width * height * 4);\n        convertBlackAndWhiteToRGBA({\n          src: imgArray,\n          dest: data,\n          width,\n          height,\n          nonBlackColor: 0,\n          inverseDecode\n        });\n        return ImageResizer.createImage({\n          kind: ImageKind.RGBA_32BPP,\n          data,\n          width,\n          height,\n          interpolate\n        });\n      }\n      const canvas = new OffscreenCanvas(width, height);\n      const ctx = canvas.getContext(\"2d\");\n      const imgData = ctx.createImageData(width, height);\n      convertBlackAndWhiteToRGBA({\n        src: imgArray,\n        dest: imgData.data,\n        width,\n        height,\n        nonBlackColor: 0,\n        inverseDecode\n      });\n      ctx.putImageData(imgData, 0, 0);\n      const bitmap = canvas.transferToImageBitmap();\n      return {\n        data: null,\n        width,\n        height,\n        interpolate,\n        bitmap\n      };\n    }\n    return this.createRawMask({\n      imgArray,\n      width,\n      height,\n      inverseDecode,\n      imageIsFromDecodeStream,\n      interpolate\n    });\n  }\n  get drawWidth() {\n    return Math.max(this.width, this.smask?.width || 0, this.mask?.width || 0);\n  }\n  get drawHeight() {\n    return Math.max(this.height, this.smask?.height || 0, this.mask?.height || 0);\n  }\n  decodeBuffer(buffer) {\n    const bpc = this.bpc;\n    const numComps = this.numComps;\n    const decodeAddends = this.decodeAddends;\n    const decodeCoefficients = this.decodeCoefficients;\n    const max = (1 << bpc) - 1;\n    let i, ii;\n    if (bpc === 1) {\n      for (i = 0, ii = buffer.length; i < ii; i++) {\n        buffer[i] = +!buffer[i];\n      }\n      return;\n    }\n    let index = 0;\n    for (i = 0, ii = this.width * this.height; i < ii; i++) {\n      for (let j = 0; j < numComps; j++) {\n        buffer[index] = decodeAndClamp(buffer[index], decodeAddends[j], decodeCoefficients[j], max);\n        index++;\n      }\n    }\n  }\n  getComponents(buffer) {\n    const bpc = this.bpc;\n    if (bpc === 8) {\n      return buffer;\n    }\n    const width = this.width;\n    const height = this.height;\n    const numComps = this.numComps;\n    const length = width * height * numComps;\n    let bufferPos = 0;\n    let output;\n    if (bpc <= 8) {\n      output = new Uint8Array(length);\n    } else if (bpc <= 16) {\n      output = new Uint16Array(length);\n    } else {\n      output = new Uint32Array(length);\n    }\n    const rowComps = width * numComps;\n    const max = (1 << bpc) - 1;\n    let i = 0,\n      ii,\n      buf;\n    if (bpc === 1) {\n      let mask, loop1End, loop2End;\n      for (let j = 0; j < height; j++) {\n        loop1End = i + (rowComps & ~7);\n        loop2End = i + rowComps;\n        while (i < loop1End) {\n          buf = buffer[bufferPos++];\n          output[i] = buf >> 7 & 1;\n          output[i + 1] = buf >> 6 & 1;\n          output[i + 2] = buf >> 5 & 1;\n          output[i + 3] = buf >> 4 & 1;\n          output[i + 4] = buf >> 3 & 1;\n          output[i + 5] = buf >> 2 & 1;\n          output[i + 6] = buf >> 1 & 1;\n          output[i + 7] = buf & 1;\n          i += 8;\n        }\n        if (i < loop2End) {\n          buf = buffer[bufferPos++];\n          mask = 128;\n          while (i < loop2End) {\n            output[i++] = +!!(buf & mask);\n            mask >>= 1;\n          }\n        }\n      }\n    } else {\n      let bits = 0;\n      buf = 0;\n      for (i = 0, ii = length; i < ii; ++i) {\n        if (i % rowComps === 0) {\n          buf = 0;\n          bits = 0;\n        }\n        while (bits < bpc) {\n          buf = buf << 8 | buffer[bufferPos++];\n          bits += 8;\n        }\n        const remainingBits = bits - bpc;\n        let value = buf >> remainingBits;\n        if (value < 0) {\n          value = 0;\n        } else if (value > max) {\n          value = max;\n        }\n        output[i] = value;\n        buf &= (1 << remainingBits) - 1;\n        bits = remainingBits;\n      }\n    }\n    return output;\n  }\n  fillOpacity(rgbaBuf, width, height, actualHeight, image) {\n    const smask = this.smask;\n    const mask = this.mask;\n    let alphaBuf, sw, sh, i, ii, j;\n    if (smask) {\n      sw = smask.width;\n      sh = smask.height;\n      alphaBuf = new Uint8ClampedArray(sw * sh);\n      smask.fillGrayBuffer(alphaBuf);\n      if (sw !== width || sh !== height) {\n        alphaBuf = resizeImageMask(alphaBuf, smask.bpc, sw, sh, width, height);\n      }\n    } else if (mask) {\n      if (mask instanceof PDFImage) {\n        sw = mask.width;\n        sh = mask.height;\n        alphaBuf = new Uint8ClampedArray(sw * sh);\n        mask.numComps = 1;\n        mask.fillGrayBuffer(alphaBuf);\n        for (i = 0, ii = sw * sh; i < ii; ++i) {\n          alphaBuf[i] = 255 - alphaBuf[i];\n        }\n        if (sw !== width || sh !== height) {\n          alphaBuf = resizeImageMask(alphaBuf, mask.bpc, sw, sh, width, height);\n        }\n      } else if (Array.isArray(mask)) {\n        alphaBuf = new Uint8ClampedArray(width * height);\n        const numComps = this.numComps;\n        for (i = 0, ii = width * height; i < ii; ++i) {\n          let opacity = 0;\n          const imageOffset = i * numComps;\n          for (j = 0; j < numComps; ++j) {\n            const color = image[imageOffset + j];\n            const maskOffset = j * 2;\n            if (color < mask[maskOffset] || color > mask[maskOffset + 1]) {\n              opacity = 255;\n              break;\n            }\n          }\n          alphaBuf[i] = opacity;\n        }\n      } else {\n        throw new FormatError(\"Unknown mask format.\");\n      }\n    }\n    if (alphaBuf) {\n      for (i = 0, j = 3, ii = width * actualHeight; i < ii; ++i, j += 4) {\n        rgbaBuf[j] = alphaBuf[i];\n      }\n    } else {\n      for (i = 0, j = 3, ii = width * actualHeight; i < ii; ++i, j += 4) {\n        rgbaBuf[j] = 255;\n      }\n    }\n  }\n  undoPreblend(buffer, width, height) {\n    const matte = this.smask?.matte;\n    if (!matte) {\n      return;\n    }\n    const matteRgb = this.colorSpace.getRgb(matte, 0);\n    const matteR = matteRgb[0];\n    const matteG = matteRgb[1];\n    const matteB = matteRgb[2];\n    const length = width * height * 4;\n    for (let i = 0; i < length; i += 4) {\n      const alpha = buffer[i + 3];\n      if (alpha === 0) {\n        buffer[i] = 255;\n        buffer[i + 1] = 255;\n        buffer[i + 2] = 255;\n        continue;\n      }\n      const k = 255 / alpha;\n      buffer[i] = (buffer[i] - matteR) * k + matteR;\n      buffer[i + 1] = (buffer[i + 1] - matteG) * k + matteG;\n      buffer[i + 2] = (buffer[i + 2] - matteB) * k + matteB;\n    }\n  }\n  async createImageData(forceRGBA = false, isOffscreenCanvasSupported = false) {\n    const drawWidth = this.drawWidth;\n    const drawHeight = this.drawHeight;\n    const imgData = {\n      width: drawWidth,\n      height: drawHeight,\n      interpolate: this.interpolate,\n      kind: 0,\n      data: null\n    };\n    const numComps = this.numComps;\n    const originalWidth = this.width;\n    const originalHeight = this.height;\n    const bpc = this.bpc;\n    const rowBytes = originalWidth * numComps * bpc + 7 >> 3;\n    const mustBeResized = isOffscreenCanvasSupported && ImageResizer.needsToBeResized(drawWidth, drawHeight);\n    if (!forceRGBA) {\n      let kind;\n      if (this.colorSpace.name === \"DeviceGray\" && bpc === 1) {\n        kind = ImageKind.GRAYSCALE_1BPP;\n      } else if (this.colorSpace.name === \"DeviceRGB\" && bpc === 8 && !this.needsDecode) {\n        kind = ImageKind.RGB_24BPP;\n      }\n      if (kind && !this.smask && !this.mask && !this.interpolate && drawWidth === originalWidth && drawHeight === originalHeight) {\n        const data = this.getImageBytes(originalHeight * rowBytes, {});\n        if (isOffscreenCanvasSupported) {\n          if (mustBeResized) {\n            return ImageResizer.createImage({\n              data,\n              kind,\n              width: drawWidth,\n              height: drawHeight,\n              interpolate: this.interpolate\n            }, this.needsDecode);\n          }\n          return this.createBitmap(kind, originalWidth, originalHeight, data);\n        }\n        imgData.kind = kind;\n        imgData.data = data;\n        if (this.needsDecode) {\n          assert(kind === ImageKind.GRAYSCALE_1BPP, \"PDFImage.createImageData: The image must be grayscale.\");\n          const buffer = imgData.data;\n          for (let i = 0, ii = buffer.length; i < ii; i++) {\n            buffer[i] ^= 0xff;\n          }\n        }\n        return imgData;\n      }\n      if (this.image instanceof JpegStream && !this.smask && !this.mask && !this.needsDecode) {\n        let imageLength = originalHeight * rowBytes;\n        if (isOffscreenCanvasSupported && !mustBeResized) {\n          let isHandled = false;\n          switch (this.colorSpace.name) {\n            case \"DeviceGray\":\n              imageLength *= 4;\n              isHandled = true;\n              break;\n            case \"DeviceRGB\":\n              imageLength = imageLength / 3 * 4;\n              isHandled = true;\n              break;\n            case \"DeviceCMYK\":\n              isHandled = true;\n              break;\n          }\n          if (isHandled) {\n            const rgba = this.getImageBytes(imageLength, {\n              drawWidth,\n              drawHeight,\n              forceRGBA: true\n            });\n            return this.createBitmap(ImageKind.RGBA_32BPP, drawWidth, drawHeight, rgba);\n          }\n        } else {\n          switch (this.colorSpace.name) {\n            case \"DeviceGray\":\n              imageLength *= 3;\n            case \"DeviceRGB\":\n            case \"DeviceCMYK\":\n              imgData.kind = ImageKind.RGB_24BPP;\n              imgData.data = this.getImageBytes(imageLength, {\n                drawWidth,\n                drawHeight,\n                forceRGB: true\n              });\n              if (mustBeResized) {\n                return ImageResizer.createImage(imgData);\n              }\n              return imgData;\n          }\n        }\n      }\n    }\n    const imgArray = this.getImageBytes(originalHeight * rowBytes, {\n      internal: true\n    });\n    const actualHeight = 0 | imgArray.length / rowBytes * drawHeight / originalHeight;\n    const comps = this.getComponents(imgArray);\n    let alpha01, maybeUndoPreblend;\n    let canvas, ctx, canvasImgData, data;\n    if (isOffscreenCanvasSupported && !mustBeResized) {\n      canvas = new OffscreenCanvas(drawWidth, drawHeight);\n      ctx = canvas.getContext(\"2d\");\n      canvasImgData = ctx.createImageData(drawWidth, drawHeight);\n      data = canvasImgData.data;\n    }\n    imgData.kind = ImageKind.RGBA_32BPP;\n    if (!forceRGBA && !this.smask && !this.mask) {\n      if (!isOffscreenCanvasSupported || mustBeResized) {\n        imgData.kind = ImageKind.RGB_24BPP;\n        data = new Uint8ClampedArray(drawWidth * drawHeight * 3);\n        alpha01 = 0;\n      } else {\n        const arr = new Uint32Array(data.buffer);\n        arr.fill(FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff);\n        alpha01 = 1;\n      }\n      maybeUndoPreblend = false;\n    } else {\n      if (!isOffscreenCanvasSupported || mustBeResized) {\n        data = new Uint8ClampedArray(drawWidth * drawHeight * 4);\n      }\n      alpha01 = 1;\n      maybeUndoPreblend = true;\n      this.fillOpacity(data, drawWidth, drawHeight, actualHeight, comps);\n    }\n    if (this.needsDecode) {\n      this.decodeBuffer(comps);\n    }\n    this.colorSpace.fillRgb(data, originalWidth, originalHeight, drawWidth, drawHeight, actualHeight, bpc, comps, alpha01);\n    if (maybeUndoPreblend) {\n      this.undoPreblend(data, drawWidth, actualHeight);\n    }\n    if (isOffscreenCanvasSupported && !mustBeResized) {\n      ctx.putImageData(canvasImgData, 0, 0);\n      const bitmap = canvas.transferToImageBitmap();\n      return {\n        data: null,\n        width: drawWidth,\n        height: drawHeight,\n        bitmap,\n        interpolate: this.interpolate\n      };\n    }\n    imgData.data = data;\n    if (mustBeResized) {\n      return ImageResizer.createImage(imgData);\n    }\n    return imgData;\n  }\n  fillGrayBuffer(buffer) {\n    const numComps = this.numComps;\n    if (numComps !== 1) {\n      throw new FormatError(`Reading gray scale from a color image: ${numComps}`);\n    }\n    const width = this.width;\n    const height = this.height;\n    const bpc = this.bpc;\n    const rowBytes = width * numComps * bpc + 7 >> 3;\n    const imgArray = this.getImageBytes(height * rowBytes, {\n      internal: true\n    });\n    const comps = this.getComponents(imgArray);\n    let i, length;\n    if (bpc === 1) {\n      length = width * height;\n      if (this.needsDecode) {\n        for (i = 0; i < length; ++i) {\n          buffer[i] = comps[i] - 1 & 255;\n        }\n      } else {\n        for (i = 0; i < length; ++i) {\n          buffer[i] = -comps[i] & 255;\n        }\n      }\n      return;\n    }\n    if (this.needsDecode) {\n      this.decodeBuffer(comps);\n    }\n    length = width * height;\n    const scale = 255 / ((1 << bpc) - 1);\n    for (i = 0; i < length; ++i) {\n      buffer[i] = scale * comps[i];\n    }\n  }\n  createBitmap(kind, width, height, src) {\n    const canvas = new OffscreenCanvas(width, height);\n    const ctx = canvas.getContext(\"2d\");\n    let imgData;\n    if (kind === ImageKind.RGBA_32BPP) {\n      imgData = new ImageData(src, width, height);\n    } else {\n      imgData = ctx.createImageData(width, height);\n      convertToRGBA({\n        kind,\n        src,\n        dest: new Uint32Array(imgData.data.buffer),\n        width,\n        height,\n        inverseDecode: this.needsDecode\n      });\n    }\n    ctx.putImageData(imgData, 0, 0);\n    const bitmap = canvas.transferToImageBitmap();\n    return {\n      data: null,\n      width,\n      height,\n      bitmap,\n      interpolate: this.interpolate\n    };\n  }\n  getImageBytes(length, {\n    drawWidth,\n    drawHeight,\n    forceRGBA = false,\n    forceRGB = false,\n    internal = false\n  }) {\n    this.image.reset();\n    this.image.drawWidth = drawWidth || this.width;\n    this.image.drawHeight = drawHeight || this.height;\n    this.image.forceRGBA = !!forceRGBA;\n    this.image.forceRGB = !!forceRGB;\n    const imageBytes = this.image.getBytes(length, this.ignoreColorSpace);\n    if (internal || this.image instanceof DecodeStream) {\n      return imageBytes;\n    }\n    assert(imageBytes instanceof Uint8Array, 'PDFImage.getImageBytes: Unsupported \"imageBytes\" type.');\n    return new Uint8Array(imageBytes);\n  }\n}\n\n;// ./src/core/evaluator.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst DefaultPartialEvaluatorOptions = Object.freeze({\n  maxImageSize: -1,\n  disableFontFace: false,\n  ignoreErrors: false,\n  isEvalSupported: true,\n  isOffscreenCanvasSupported: false,\n  canvasMaxAreaInBytes: -1,\n  fontExtraProperties: false,\n  useSystemFonts: true,\n  cMapUrl: null,\n  standardFontDataUrl: null\n});\nconst PatternType = {\n  TILING: 1,\n  SHADING: 2\n};\nconst TEXT_CHUNK_BATCH_SIZE = 10;\nconst deferred = Promise.resolve();\nfunction normalizeBlendMode(value, parsingArray = false) {\n  if (Array.isArray(value)) {\n    for (const val of value) {\n      const maybeBM = normalizeBlendMode(val, true);\n      if (maybeBM) {\n        return maybeBM;\n      }\n    }\n    warn(`Unsupported blend mode Array: ${value}`);\n    return \"source-over\";\n  }\n  if (!(value instanceof Name)) {\n    if (parsingArray) {\n      return null;\n    }\n    return \"source-over\";\n  }\n  switch (value.name) {\n    case \"Normal\":\n    case \"Compatible\":\n      return \"source-over\";\n    case \"Multiply\":\n      return \"multiply\";\n    case \"Screen\":\n      return \"screen\";\n    case \"Overlay\":\n      return \"overlay\";\n    case \"Darken\":\n      return \"darken\";\n    case \"Lighten\":\n      return \"lighten\";\n    case \"ColorDodge\":\n      return \"color-dodge\";\n    case \"ColorBurn\":\n      return \"color-burn\";\n    case \"HardLight\":\n      return \"hard-light\";\n    case \"SoftLight\":\n      return \"soft-light\";\n    case \"Difference\":\n      return \"difference\";\n    case \"Exclusion\":\n      return \"exclusion\";\n    case \"Hue\":\n      return \"hue\";\n    case \"Saturation\":\n      return \"saturation\";\n    case \"Color\":\n      return \"color\";\n    case \"Luminosity\":\n      return \"luminosity\";\n  }\n  if (parsingArray) {\n    return null;\n  }\n  warn(`Unsupported blend mode: ${value.name}`);\n  return \"source-over\";\n}\nfunction incrementCachedImageMaskCount(data) {\n  if (data.fn === OPS.paintImageMaskXObject && data.args[0]?.count > 0) {\n    data.args[0].count++;\n  }\n}\nclass TimeSlotManager {\n  static TIME_SLOT_DURATION_MS = 20;\n  static CHECK_TIME_EVERY = 100;\n  constructor() {\n    this.reset();\n  }\n  check() {\n    if (++this.checked < TimeSlotManager.CHECK_TIME_EVERY) {\n      return false;\n    }\n    this.checked = 0;\n    return this.endTime <= Date.now();\n  }\n  reset() {\n    this.endTime = Date.now() + TimeSlotManager.TIME_SLOT_DURATION_MS;\n    this.checked = 0;\n  }\n}\nclass PartialEvaluator {\n  constructor({\n    xref,\n    handler,\n    pageIndex,\n    idFactory,\n    fontCache,\n    builtInCMapCache,\n    standardFontDataCache,\n    globalImageCache,\n    systemFontCache,\n    imageOutLlamaParse,\n    disableImageExtraction,\n    options = null\n  }) {\n    this.xref = xref;\n    this.handler = handler;\n    this.pageIndex = pageIndex;\n    this.idFactory = idFactory;\n    this.fontCache = fontCache;\n    this.builtInCMapCache = builtInCMapCache;\n    this.standardFontDataCache = standardFontDataCache;\n    this.globalImageCache = globalImageCache;\n    this.systemFontCache = systemFontCache;\n    this.options = options || DefaultPartialEvaluatorOptions;\n    this.parsingType3Font = false;\n    this.imageOutLlamaParse = imageOutLlamaParse;\n    this.disableImageExtraction = disableImageExtraction;\n    this._regionalImageCache = new RegionalImageCache();\n    this._fetchBuiltInCMapBound = this.fetchBuiltInCMap.bind(this);\n    ImageResizer.setMaxArea(this.options.canvasMaxAreaInBytes);\n  }\n  get _pdfFunctionFactory() {\n    const pdfFunctionFactory = new PDFFunctionFactory({\n      xref: this.xref,\n      isEvalSupported: this.options.isEvalSupported\n    });\n    return shadow(this, \"_pdfFunctionFactory\", pdfFunctionFactory);\n  }\n  clone(newOptions = null) {\n    const newEvaluator = Object.create(this);\n    newEvaluator.options = Object.assign(Object.create(null), this.options, newOptions);\n    return newEvaluator;\n  }\n  hasBlendModes(resources, nonBlendModesSet) {\n    if (!(resources instanceof Dict)) {\n      return false;\n    }\n    if (resources.objId && nonBlendModesSet.has(resources.objId)) {\n      return false;\n    }\n    const processed = new RefSet(nonBlendModesSet);\n    if (resources.objId) {\n      processed.put(resources.objId);\n    }\n    const nodes = [resources],\n      xref = this.xref;\n    while (nodes.length) {\n      const node = nodes.shift();\n      const graphicStates = node.get(\"ExtGState\");\n      if (graphicStates instanceof Dict) {\n        for (let graphicState of graphicStates.getRawValues()) {\n          if (graphicState instanceof Ref) {\n            if (processed.has(graphicState)) {\n              continue;\n            }\n            try {\n              graphicState = xref.fetch(graphicState);\n            } catch (ex) {\n              processed.put(graphicState);\n              info(`hasBlendModes - ignoring ExtGState: \"${ex}\".`);\n              continue;\n            }\n          }\n          if (!(graphicState instanceof Dict)) {\n            continue;\n          }\n          if (graphicState.objId) {\n            processed.put(graphicState.objId);\n          }\n          const bm = graphicState.get(\"BM\");\n          if (bm instanceof Name) {\n            if (bm.name !== \"Normal\") {\n              return true;\n            }\n            continue;\n          }\n          if (bm !== undefined && Array.isArray(bm)) {\n            for (const element of bm) {\n              if (element instanceof Name && element.name !== \"Normal\") {\n                return true;\n              }\n            }\n          }\n        }\n      }\n      const xObjects = node.get(\"XObject\");\n      if (!(xObjects instanceof Dict)) {\n        continue;\n      }\n      for (let xObject of xObjects.getRawValues()) {\n        if (xObject instanceof Ref) {\n          if (processed.has(xObject)) {\n            continue;\n          }\n          try {\n            xObject = xref.fetch(xObject);\n          } catch (ex) {\n            processed.put(xObject);\n            info(`hasBlendModes - ignoring XObject: \"${ex}\".`);\n            continue;\n          }\n        }\n        if (!(xObject instanceof BaseStream)) {\n          continue;\n        }\n        if (xObject.dict.objId) {\n          processed.put(xObject.dict.objId);\n        }\n        const xResources = xObject.dict.get(\"Resources\");\n        if (!(xResources instanceof Dict)) {\n          continue;\n        }\n        if (xResources.objId && processed.has(xResources.objId)) {\n          continue;\n        }\n        nodes.push(xResources);\n        if (xResources.objId) {\n          processed.put(xResources.objId);\n        }\n      }\n    }\n    for (const ref of processed) {\n      nonBlendModesSet.put(ref);\n    }\n    return false;\n  }\n  async fetchBuiltInCMap(name) {\n    const cachedData = this.builtInCMapCache.get(name);\n    if (cachedData) {\n      return cachedData;\n    }\n    let data;\n    if (this.options.cMapUrl !== null) {\n      const url = `${this.options.cMapUrl}${name}.bcmap`;\n      const response = await fetch(url);\n      if (!response.ok) {\n        throw new Error(`fetchBuiltInCMap: failed to fetch file \"${url}\" with \"${response.statusText}\".`);\n      }\n      data = {\n        cMapData: new Uint8Array(await response.arrayBuffer()),\n        compressionType: CMapCompressionType.BINARY\n      };\n    } else {\n      data = await this.handler.sendWithPromise(\"FetchBuiltInCMap\", {\n        name\n      });\n    }\n    if (data.compressionType !== CMapCompressionType.NONE) {\n      this.builtInCMapCache.set(name, data);\n    }\n    return data;\n  }\n  async fetchStandardFontData(name) {\n    const cachedData = this.standardFontDataCache.get(name);\n    if (cachedData) {\n      return new Stream(cachedData);\n    }\n    if (this.options.useSystemFonts && name !== \"Symbol\" && name !== \"ZapfDingbats\") {\n      return null;\n    }\n    const standardFontNameToFileName = getFontNameToFileMap(),\n      filename = standardFontNameToFileName[name];\n    let data;\n    if (this.options.standardFontDataUrl !== null) {\n      const url = `${this.options.standardFontDataUrl}${filename}`;\n      const response = await fetch(url);\n      if (!response.ok) {\n        warn(`fetchStandardFontData: failed to fetch file \"${url}\" with \"${response.statusText}\".`);\n      } else {\n        data = new Uint8Array(await response.arrayBuffer());\n      }\n    } else {\n      try {\n        data = await this.handler.sendWithPromise(\"FetchStandardFontData\", {\n          filename\n        });\n      } catch (e) {\n        warn(`fetchStandardFontData: failed to fetch file \"${filename}\" with \"${e}\".`);\n      }\n    }\n    if (!data) {\n      return null;\n    }\n    this.standardFontDataCache.set(name, data);\n    return new Stream(data);\n  }\n  async buildFormXObject(resources, xobj, smask, operatorList, task, initialState, localColorSpaceCache) {\n    const dict = xobj.dict;\n    const matrix = dict.getArray(\"Matrix\");\n    let bbox = dict.getArray(\"BBox\");\n    bbox = Array.isArray(bbox) && bbox.length === 4 ? Util.normalizeRect(bbox) : null;\n    let optionalContent, groupOptions;\n    if (dict.has(\"OC\")) {\n      optionalContent = await this.parseMarkedContentProps(dict.get(\"OC\"), resources);\n    }\n    if (optionalContent !== undefined) {\n      operatorList.addOp(OPS.beginMarkedContentProps, [\"OC\", optionalContent]);\n    }\n    const group = dict.get(\"Group\");\n    if (group) {\n      groupOptions = {\n        matrix,\n        bbox,\n        smask,\n        isolated: false,\n        knockout: false\n      };\n      const groupSubtype = group.get(\"S\");\n      let colorSpace = null;\n      if (isName(groupSubtype, \"Transparency\")) {\n        groupOptions.isolated = group.get(\"I\") || false;\n        groupOptions.knockout = group.get(\"K\") || false;\n        if (group.has(\"CS\")) {\n          const cs = group.getRaw(\"CS\");\n          const cachedColorSpace = ColorSpace.getCached(cs, this.xref, localColorSpaceCache);\n          if (cachedColorSpace) {\n            colorSpace = cachedColorSpace;\n          } else {\n            colorSpace = await this.parseColorSpace({\n              cs,\n              resources,\n              localColorSpaceCache\n            });\n          }\n        }\n      }\n      if (smask?.backdrop) {\n        colorSpace ||= ColorSpace.singletons.rgb;\n        smask.backdrop = colorSpace.getRgb(smask.backdrop, 0);\n      }\n      operatorList.addOp(OPS.beginGroup, [groupOptions]);\n    }\n    const args = group ? [matrix, null] : [matrix, bbox];\n    operatorList.addOp(OPS.paintFormXObjectBegin, args);\n    await this.getOperatorList({\n      stream: xobj,\n      task,\n      resources: dict.get(\"Resources\") || resources,\n      operatorList,\n      initialState\n    });\n    operatorList.addOp(OPS.paintFormXObjectEnd, []);\n    if (group) {\n      operatorList.addOp(OPS.endGroup, [groupOptions]);\n    }\n    if (optionalContent !== undefined) {\n      operatorList.addOp(OPS.endMarkedContent, []);\n    }\n  }\n  _sendImgData(objId, imgData, cacheGlobally = false) {\n    const transfers = imgData ? [imgData.bitmap || imgData.data.buffer] : null;\n    if (this.parsingType3Font || cacheGlobally) {\n      return this.handler.send(\"commonobj\", [objId, \"Image\", imgData], transfers);\n    }\n    return this.handler.send(\"obj\", [objId, this.pageIndex, \"Image\", imgData], transfers);\n  }\n  async buildPaintImageXObject({\n    resources,\n    image,\n    isInline = false,\n    operatorList,\n    cacheKey,\n    localImageCache,\n    localColorSpaceCache,\n    outDir\n  }) {\n    if (this.disableImageExtraction) {\n      return;\n    }\n    const dict = image.dict;\n    const imageRef = dict.objId;\n    const w = dict.get(\"W\", \"Width\");\n    const h = dict.get(\"H\", \"Height\");\n    if (!(w && typeof w === \"number\") || !(h && typeof h === \"number\")) {\n      warn(\"Image dimensions are missing, or not numbers.\");\n      return;\n    }\n    const maxImageSize = this.options.maxImageSize;\n    if (maxImageSize !== -1 && w * h > maxImageSize) {\n      const msg = \"Image exceeded maximum allowed size and was removed.\";\n      if (this.options.ignoreErrors) {\n        warn(msg);\n        return;\n      }\n      throw new Error(msg);\n    }\n    let optionalContent;\n    if (dict.has(\"OC\")) {\n      optionalContent = await this.parseMarkedContentProps(dict.get(\"OC\"), resources);\n    }\n    const imageMask = dict.get(\"IM\", \"ImageMask\") || false;\n    let imgData, args;\n    if (imageMask) {\n      const interpolate = dict.get(\"I\", \"Interpolate\");\n      const bitStrideLength = w + 7 >> 3;\n      const imgArray = image.getBytes(bitStrideLength * h);\n      const decode = dict.getArray(\"D\", \"Decode\");\n      if (this.parsingType3Font) {\n        imgData = PDFImage.createRawMask({\n          imgArray,\n          width: w,\n          height: h,\n          imageIsFromDecodeStream: image instanceof DecodeStream,\n          inverseDecode: decode?.[0] > 0,\n          interpolate\n        });\n        imgData.cached = !!cacheKey;\n        args = [imgData];\n        operatorList.addImageOps(OPS.paintImageMaskXObject, args, optionalContent);\n        if (cacheKey) {\n          const cacheData = {\n            fn: OPS.paintImageMaskXObject,\n            args,\n            optionalContent\n          };\n          localImageCache.set(cacheKey, imageRef, cacheData);\n          if (imageRef) {\n            this._regionalImageCache.set(null, imageRef, cacheData);\n          }\n        }\n        return;\n      }\n      imgData = await PDFImage.createMask({\n        imgArray,\n        width: w,\n        height: h,\n        imageIsFromDecodeStream: image instanceof DecodeStream,\n        inverseDecode: decode?.[0] > 0,\n        interpolate,\n        isOffscreenCanvasSupported: this.options.isOffscreenCanvasSupported\n      });\n      if (imgData.isSingleOpaquePixel) {\n        operatorList.addImageOps(OPS.paintSolidColorImageMask, [], optionalContent);\n        if (cacheKey) {\n          const cacheData = {\n            fn: OPS.paintSolidColorImageMask,\n            args: [],\n            optionalContent\n          };\n          localImageCache.set(cacheKey, imageRef, cacheData);\n          if (imageRef) {\n            this._regionalImageCache.set(null, imageRef, cacheData);\n          }\n        }\n        return;\n      }\n      const objId = `mask_${this.idFactory.createObjId()}`;\n      operatorList.addDependency(objId);\n      imgData.dataLen = imgData.bitmap ? imgData.width * imgData.height * 4 : imgData.data.length;\n      this._sendImgData(objId, imgData);\n      args = [{\n        data: objId,\n        width: imgData.width,\n        height: imgData.height,\n        interpolate: imgData.interpolate,\n        count: 1\n      }];\n      operatorList.addImageOps(OPS.paintImageMaskXObject, args, optionalContent);\n      if (cacheKey) {\n        const cacheData = {\n          fn: OPS.paintImageMaskXObject,\n          args,\n          optionalContent\n        };\n        localImageCache.set(cacheKey, imageRef, cacheData);\n        if (imageRef) {\n          this._regionalImageCache.set(null, imageRef, cacheData);\n        }\n      }\n      return;\n    }\n    const SMALL_IMAGE_DIMENSIONS = 20;\n    if (isInline && !dict.has(\"SMask\") && !dict.has(\"Mask\") && w + h < SMALL_IMAGE_DIMENSIONS) {\n      const imageObj = new PDFImage({\n        xref: this.xref,\n        res: resources,\n        image,\n        isInline,\n        pdfFunctionFactory: this._pdfFunctionFactory,\n        localColorSpaceCache\n      });\n      imgData = await imageObj.createImageData(true, false);\n      operatorList.isOffscreenCanvasSupported = this.options.isOffscreenCanvasSupported;\n      operatorList.addImageOps(OPS.paintInlineImageXObject, [imgData], optionalContent);\n      return;\n    }\n    const imageObj = new PDFImage({\n      xref: this.xref,\n      res: resources,\n      image,\n      isInline,\n      pdfFunctionFactory: this._pdfFunctionFactory,\n      localColorSpaceCache\n    });\n    imgData = await imageObj.createImageData(true, false);\n    let objId = `img_${this.idFactory.createObjId()}`,\n      cacheGlobally = false;\n    if (image) {\n      if (image.stream && image.stream.bytes && !image.isJbig2) {\n        await promises_namespaceObject.writeFile(`${this.imageOutLlamaParse}${objId}.png`, image.stream.bytes.slice(image.stream.start, image.stream.end));\n        image.isExtracted = true;\n        image.extractedPath = `${this.imageOutLlamaParse}${objId}.png`;\n      } else {}\n    }\n    if (this.parsingType3Font) {\n      objId = `${this.idFactory.getDocId()}_type3_${objId}`;\n    } else if (cacheKey && imageRef) {\n      cacheGlobally = this.globalImageCache.shouldCache(imageRef, this.pageIndex);\n      if (cacheGlobally) {\n        assert(!isInline, \"Cannot cache an inline image globally.\");\n        objId = `${this.idFactory.getDocId()}_${objId}`;\n      }\n    }\n    operatorList.addDependency(objId);\n    args = [objId, w, h, image.isExtracted, image.extractedPath];\n    operatorList.addImageOps(OPS.paintImageXObject, args, optionalContent);\n    if (cacheGlobally && w * h > 250000) {\n      const localLength = await this.handler.sendWithPromise(\"commonobj\", [objId, \"CopyLocalImage\", {\n        imageRef\n      }]);\n      if (localLength) {\n        this.globalImageCache.setData(imageRef, {\n          objId,\n          fn: OPS.paintImageXObject,\n          args,\n          optionalContent,\n          byteSize: 0\n        });\n        this.globalImageCache.addByteSize(imageRef, localLength);\n        return;\n      }\n    }\n    PDFImage.buildImage({\n      xref: this.xref,\n      res: resources,\n      image,\n      isInline,\n      pdfFunctionFactory: this._pdfFunctionFactory,\n      localColorSpaceCache\n    }).then(async imageObj => {\n      if (imageObj.image.isExtracted) {\n        return this.handler.send(\"obj\", [objId, this.pageIndex, \"Image\", image.extractedPath]);\n      }\n      imgData = await imageObj.createImageData(false, this.options.isOffscreenCanvasSupported);\n      imgData.dataLen = imgData.bitmap ? imgData.width * imgData.height * 4 : imgData.data.length;\n      imgData.ref = imageRef;\n      if (cacheGlobally) {\n        this.globalImageCache.addByteSize(imageRef, imgData.dataLen);\n      }\n      return this._sendImgData(objId, imgData, cacheGlobally);\n    }).catch(reason => {\n      warn(`Unable to decode image \"${objId}\": \"${reason}\".`);\n      return this._sendImgData(objId, null, cacheGlobally);\n    });\n    if (cacheKey) {\n      const cacheData = {\n        fn: OPS.paintImageXObject,\n        args,\n        optionalContent\n      };\n      localImageCache.set(cacheKey, imageRef, cacheData);\n      if (imageRef) {\n        this._regionalImageCache.set(null, imageRef, cacheData);\n        if (cacheGlobally) {\n          this.globalImageCache.setData(imageRef, {\n            objId,\n            fn: OPS.paintImageXObject,\n            args,\n            optionalContent,\n            byteSize: 0\n          });\n        }\n      }\n    }\n  }\n  handleSMask(smask, resources, operatorList, task, stateManager, localColorSpaceCache) {\n    const smaskContent = smask.get(\"G\");\n    const smaskOptions = {\n      subtype: smask.get(\"S\").name,\n      backdrop: smask.get(\"BC\")\n    };\n    const transferObj = smask.get(\"TR\");\n    if (isPDFFunction(transferObj)) {\n      const transferFn = this._pdfFunctionFactory.create(transferObj);\n      const transferMap = new Uint8Array(256);\n      const tmp = new Float32Array(1);\n      for (let i = 0; i < 256; i++) {\n        tmp[0] = i / 255;\n        transferFn(tmp, 0, tmp, 0);\n        transferMap[i] = tmp[0] * 255 | 0;\n      }\n      smaskOptions.transferMap = transferMap;\n    }\n    return this.buildFormXObject(resources, smaskContent, smaskOptions, operatorList, task, stateManager.state.clone(), localColorSpaceCache);\n  }\n  handleTransferFunction(tr) {\n    let transferArray;\n    if (Array.isArray(tr)) {\n      transferArray = tr;\n    } else if (isPDFFunction(tr)) {\n      transferArray = [tr];\n    } else {\n      return null;\n    }\n    const transferMaps = [];\n    let numFns = 0,\n      numEffectfulFns = 0;\n    for (const entry of transferArray) {\n      const transferObj = this.xref.fetchIfRef(entry);\n      numFns++;\n      if (isName(transferObj, \"Identity\")) {\n        transferMaps.push(null);\n        continue;\n      } else if (!isPDFFunction(transferObj)) {\n        return null;\n      }\n      const transferFn = this._pdfFunctionFactory.create(transferObj);\n      const transferMap = new Uint8Array(256),\n        tmp = new Float32Array(1);\n      for (let j = 0; j < 256; j++) {\n        tmp[0] = j / 255;\n        transferFn(tmp, 0, tmp, 0);\n        transferMap[j] = tmp[0] * 255 | 0;\n      }\n      transferMaps.push(transferMap);\n      numEffectfulFns++;\n    }\n    if (!(numFns === 1 || numFns === 4)) {\n      return null;\n    }\n    if (numEffectfulFns === 0) {\n      return null;\n    }\n    return transferMaps;\n  }\n  handleTilingType(fn, color, resources, pattern, patternDict, operatorList, task, localTilingPatternCache) {\n    const tilingOpList = new OperatorList();\n    const patternResources = Dict.merge({\n      xref: this.xref,\n      dictArray: [patternDict.get(\"Resources\"), resources]\n    });\n    return this.getOperatorList({\n      stream: pattern,\n      task,\n      resources: patternResources,\n      operatorList: tilingOpList\n    }).then(function () {\n      const operatorListIR = tilingOpList.getIR();\n      const tilingPatternIR = getTilingPatternIR(operatorListIR, patternDict, color);\n      operatorList.addDependencies(tilingOpList.dependencies);\n      operatorList.addOp(fn, tilingPatternIR);\n      if (patternDict.objId) {\n        localTilingPatternCache.set(null, patternDict.objId, {\n          operatorListIR,\n          dict: patternDict\n        });\n      }\n    }).catch(reason => {\n      if (reason instanceof AbortException) {\n        return;\n      }\n      if (this.options.ignoreErrors) {\n        warn(`handleTilingType - ignoring pattern: \"${reason}\".`);\n        return;\n      }\n      throw reason;\n    });\n  }\n  async handleSetFont(resources, fontArgs, fontRef, operatorList, task, state, fallbackFontDict = null, cssFontInfo = null) {\n    const fontName = fontArgs?.[0] instanceof Name ? fontArgs[0].name : null;\n    let translated = await this.loadFont(fontName, fontRef, resources, fallbackFontDict, cssFontInfo);\n    if (translated.font.isType3Font) {\n      try {\n        await translated.loadType3Data(this, resources, task);\n        operatorList.addDependencies(translated.type3Dependencies);\n      } catch (reason) {\n        translated = new TranslatedFont({\n          loadedName: \"g_font_error\",\n          font: new ErrorFont(`Type3 font load error: ${reason}`),\n          dict: translated.font,\n          evaluatorOptions: this.options\n        });\n      }\n    }\n    state.font = translated.font;\n    translated.send(this.handler);\n    return translated.loadedName;\n  }\n  handleText(chars, state) {\n    const font = state.font;\n    const glyphs = font.charsToGlyphs(chars);\n    if (font.data) {\n      const isAddToPathSet = !!(state.textRenderingMode & TextRenderingMode.ADD_TO_PATH_FLAG);\n      if (isAddToPathSet || state.fillColorSpace.name === \"Pattern\" || font.disableFontFace || this.options.disableFontFace) {\n        PartialEvaluator.buildFontPaths(font, glyphs, this.handler, this.options);\n      }\n    }\n    return glyphs;\n  }\n  ensureStateFont(state) {\n    if (state.font) {\n      return;\n    }\n    const reason = new FormatError(\"Missing setFont (Tf) operator before text rendering operator.\");\n    if (this.options.ignoreErrors) {\n      warn(`ensureStateFont: \"${reason}\".`);\n      return;\n    }\n    throw reason;\n  }\n  async setGState({\n    resources,\n    gState,\n    operatorList,\n    cacheKey,\n    task,\n    stateManager,\n    localGStateCache,\n    localColorSpaceCache\n  }) {\n    const gStateRef = gState.objId;\n    let isSimpleGState = true;\n    const gStateObj = [];\n    let promise = Promise.resolve();\n    for (const key of gState.getKeys()) {\n      const value = gState.get(key);\n      switch (key) {\n        case \"Type\":\n          break;\n        case \"LW\":\n        case \"LC\":\n        case \"LJ\":\n        case \"ML\":\n        case \"D\":\n        case \"RI\":\n        case \"FL\":\n        case \"CA\":\n        case \"ca\":\n          gStateObj.push([key, value]);\n          break;\n        case \"Font\":\n          isSimpleGState = false;\n          promise = promise.then(() => this.handleSetFont(resources, null, value[0], operatorList, task, stateManager.state).then(function (loadedName) {\n            operatorList.addDependency(loadedName);\n            gStateObj.push([key, [loadedName, value[1]]]);\n          }));\n          break;\n        case \"BM\":\n          gStateObj.push([key, normalizeBlendMode(value)]);\n          break;\n        case \"SMask\":\n          if (isName(value, \"None\")) {\n            gStateObj.push([key, false]);\n            break;\n          }\n          if (value instanceof Dict) {\n            isSimpleGState = false;\n            promise = promise.then(() => this.handleSMask(value, resources, operatorList, task, stateManager, localColorSpaceCache));\n            gStateObj.push([key, true]);\n          } else {\n            warn(\"Unsupported SMask type\");\n          }\n          break;\n        case \"TR\":\n          const transferMaps = this.handleTransferFunction(value);\n          gStateObj.push([key, transferMaps]);\n          break;\n        case \"OP\":\n        case \"op\":\n        case \"OPM\":\n        case \"BG\":\n        case \"BG2\":\n        case \"UCR\":\n        case \"UCR2\":\n        case \"TR2\":\n        case \"HT\":\n        case \"SM\":\n        case \"SA\":\n        case \"AIS\":\n        case \"TK\":\n          info(\"graphic state operator \" + key);\n          break;\n        default:\n          info(\"Unknown graphic state operator \" + key);\n          break;\n      }\n    }\n    await promise;\n    if (gStateObj.length > 0) {\n      operatorList.addOp(OPS.setGState, [gStateObj]);\n    }\n    if (isSimpleGState) {\n      localGStateCache.set(cacheKey, gStateRef, gStateObj);\n    }\n  }\n  loadFont(fontName, font, resources, fallbackFontDict = null, cssFontInfo = null) {\n    const errorFont = async () => {\n      return new TranslatedFont({\n        loadedName: \"g_font_error\",\n        font: new ErrorFont(`Font \"${fontName}\" is not available.`),\n        dict: font,\n        evaluatorOptions: this.options\n      });\n    };\n    let fontRef;\n    if (font) {\n      if (font instanceof Ref) {\n        fontRef = font;\n      }\n    } else {\n      const fontRes = resources.get(\"Font\");\n      if (fontRes) {\n        fontRef = fontRes.getRaw(fontName);\n      }\n    }\n    if (fontRef) {\n      if (this.parsingType3Font && this.type3FontRefs.has(fontRef)) {\n        return errorFont();\n      }\n      if (this.fontCache.has(fontRef)) {\n        return this.fontCache.get(fontRef);\n      }\n      font = this.xref.fetchIfRef(fontRef);\n    }\n    if (!(font instanceof Dict)) {\n      if (!this.options.ignoreErrors && !this.parsingType3Font) {\n        warn(`Font \"${fontName}\" is not available.`);\n        return errorFont();\n      }\n      warn(`Font \"${fontName}\" is not available -- attempting to fallback to a default font.`);\n      font = fallbackFontDict || PartialEvaluator.fallbackFontDict;\n    }\n    if (font.cacheKey && this.fontCache.has(font.cacheKey)) {\n      return this.fontCache.get(font.cacheKey);\n    }\n    const fontCapability = new PromiseCapability();\n    let preEvaluatedFont;\n    try {\n      preEvaluatedFont = this.preEvaluateFont(font);\n      preEvaluatedFont.cssFontInfo = cssFontInfo;\n    } catch (reason) {\n      warn(`loadFont - preEvaluateFont failed: \"${reason}\".`);\n      return errorFont();\n    }\n    const {\n      descriptor,\n      hash\n    } = preEvaluatedFont;\n    const fontRefIsRef = fontRef instanceof Ref;\n    let fontID;\n    if (hash && descriptor instanceof Dict) {\n      const fontAliases = descriptor.fontAliases ||= Object.create(null);\n      if (fontAliases[hash]) {\n        const aliasFontRef = fontAliases[hash].aliasRef;\n        if (fontRefIsRef && aliasFontRef && this.fontCache.has(aliasFontRef)) {\n          this.fontCache.putAlias(fontRef, aliasFontRef);\n          return this.fontCache.get(fontRef);\n        }\n      } else {\n        fontAliases[hash] = {\n          fontID: this.idFactory.createFontId()\n        };\n      }\n      if (fontRefIsRef) {\n        fontAliases[hash].aliasRef = fontRef;\n      }\n      fontID = fontAliases[hash].fontID;\n    } else {\n      fontID = this.idFactory.createFontId();\n    }\n    assert(fontID?.startsWith(\"f\"), 'The \"fontID\" must be (correctly) defined.');\n    if (fontRefIsRef) {\n      this.fontCache.put(fontRef, fontCapability.promise);\n    } else {\n      font.cacheKey = `cacheKey_${fontID}`;\n      this.fontCache.put(font.cacheKey, fontCapability.promise);\n    }\n    font.loadedName = `${this.idFactory.getDocId()}_${fontID}`;\n    this.translateFont(preEvaluatedFont).then(translatedFont => {\n      fontCapability.resolve(new TranslatedFont({\n        loadedName: font.loadedName,\n        font: translatedFont,\n        dict: font,\n        evaluatorOptions: this.options\n      }));\n    }).catch(reason => {\n      warn(`loadFont - translateFont failed: \"${reason}\".`);\n      fontCapability.resolve(new TranslatedFont({\n        loadedName: font.loadedName,\n        font: new ErrorFont(reason instanceof Error ? reason.message : reason),\n        dict: font,\n        evaluatorOptions: this.options\n      }));\n    });\n    return fontCapability.promise;\n  }\n  buildPath(operatorList, fn, args, parsingText = false) {\n    const lastIndex = operatorList.length - 1;\n    if (!args) {\n      args = [];\n    }\n    if (lastIndex < 0 || operatorList.fnArray[lastIndex] !== OPS.constructPath) {\n      if (parsingText) {\n        warn(`Encountered path operator \"${fn}\" inside of a text object.`);\n        operatorList.addOp(OPS.save, null);\n      }\n      let minMax;\n      switch (fn) {\n        case OPS.rectangle:\n          const x = args[0] + args[2];\n          const y = args[1] + args[3];\n          minMax = [Math.min(args[0], x), Math.min(args[1], y), Math.max(args[0], x), Math.max(args[1], y)];\n          break;\n        case OPS.moveTo:\n        case OPS.lineTo:\n          minMax = [args[0], args[1], args[0], args[1]];\n          break;\n        default:\n          minMax = [Infinity, Infinity, -Infinity, -Infinity];\n          break;\n      }\n      operatorList.addOp(OPS.constructPath, [[fn], args, minMax]);\n      if (parsingText) {\n        operatorList.addOp(OPS.restore, null);\n      }\n    } else {\n      const opArgs = operatorList.argsArray[lastIndex];\n      opArgs[0].push(fn);\n      opArgs[1].push(...args);\n      const minMax = opArgs[2];\n      switch (fn) {\n        case OPS.rectangle:\n          const x = args[0] + args[2];\n          const y = args[1] + args[3];\n          minMax[0] = Math.min(minMax[0], args[0], x);\n          minMax[1] = Math.min(minMax[1], args[1], y);\n          minMax[2] = Math.max(minMax[2], args[0], x);\n          minMax[3] = Math.max(minMax[3], args[1], y);\n          break;\n        case OPS.moveTo:\n        case OPS.lineTo:\n          minMax[0] = Math.min(minMax[0], args[0]);\n          minMax[1] = Math.min(minMax[1], args[1]);\n          minMax[2] = Math.max(minMax[2], args[0]);\n          minMax[3] = Math.max(minMax[3], args[1]);\n          break;\n      }\n    }\n  }\n  parseColorSpace({\n    cs,\n    resources,\n    localColorSpaceCache\n  }) {\n    return ColorSpace.parseAsync({\n      cs,\n      xref: this.xref,\n      resources,\n      pdfFunctionFactory: this._pdfFunctionFactory,\n      localColorSpaceCache\n    }).catch(reason => {\n      if (reason instanceof AbortException) {\n        return null;\n      }\n      if (this.options.ignoreErrors) {\n        warn(`parseColorSpace - ignoring ColorSpace: \"${reason}\".`);\n        return null;\n      }\n      throw reason;\n    });\n  }\n  parseShading({\n    shading,\n    resources,\n    localColorSpaceCache,\n    localShadingPatternCache\n  }) {\n    let id = localShadingPatternCache.get(shading);\n    if (!id) {\n      var shadingFill = Pattern.parseShading(shading, this.xref, resources, this._pdfFunctionFactory, localColorSpaceCache);\n      const patternIR = shadingFill.getIR();\n      id = `pattern_${this.idFactory.createObjId()}`;\n      if (this.parsingType3Font) {\n        id = `${this.idFactory.getDocId()}_type3_${id}`;\n      }\n      localShadingPatternCache.set(shading, id);\n      if (this.parsingType3Font) {\n        this.handler.send(\"commonobj\", [id, \"Pattern\", patternIR]);\n      } else {\n        this.handler.send(\"obj\", [id, this.pageIndex, \"Pattern\", patternIR]);\n      }\n    }\n    return id;\n  }\n  handleColorN(operatorList, fn, args, cs, patterns, resources, task, localColorSpaceCache, localTilingPatternCache, localShadingPatternCache) {\n    const patternName = args.pop();\n    if (patternName instanceof Name) {\n      const rawPattern = patterns.getRaw(patternName.name);\n      const localTilingPattern = rawPattern instanceof Ref && localTilingPatternCache.getByRef(rawPattern);\n      if (localTilingPattern) {\n        try {\n          const color = cs.base ? cs.base.getRgb(args, 0) : null;\n          const tilingPatternIR = getTilingPatternIR(localTilingPattern.operatorListIR, localTilingPattern.dict, color);\n          operatorList.addOp(fn, tilingPatternIR);\n          return undefined;\n        } catch {}\n      }\n      const pattern = this.xref.fetchIfRef(rawPattern);\n      if (pattern) {\n        const dict = pattern instanceof BaseStream ? pattern.dict : pattern;\n        const typeNum = dict.get(\"PatternType\");\n        if (typeNum === PatternType.TILING) {\n          const color = cs.base ? cs.base.getRgb(args, 0) : null;\n          return this.handleTilingType(fn, color, resources, pattern, dict, operatorList, task, localTilingPatternCache);\n        } else if (typeNum === PatternType.SHADING) {\n          const shading = dict.get(\"Shading\");\n          const matrix = dict.getArray(\"Matrix\");\n          const objId = this.parseShading({\n            shading,\n            resources,\n            localColorSpaceCache,\n            localShadingPatternCache\n          });\n          operatorList.addOp(fn, [\"Shading\", objId, matrix]);\n          return undefined;\n        }\n        throw new FormatError(`Unknown PatternType: ${typeNum}`);\n      }\n    }\n    throw new FormatError(`Unknown PatternName: ${patternName}`);\n  }\n  _parseVisibilityExpression(array, nestingCounter, currentResult) {\n    const MAX_NESTING = 10;\n    if (++nestingCounter > MAX_NESTING) {\n      warn(\"Visibility expression is too deeply nested\");\n      return;\n    }\n    const length = array.length;\n    const operator = this.xref.fetchIfRef(array[0]);\n    if (length < 2 || !(operator instanceof Name)) {\n      warn(\"Invalid visibility expression\");\n      return;\n    }\n    switch (operator.name) {\n      case \"And\":\n      case \"Or\":\n      case \"Not\":\n        currentResult.push(operator.name);\n        break;\n      default:\n        warn(`Invalid operator ${operator.name} in visibility expression`);\n        return;\n    }\n    for (let i = 1; i < length; i++) {\n      const raw = array[i];\n      const object = this.xref.fetchIfRef(raw);\n      if (Array.isArray(object)) {\n        const nestedResult = [];\n        currentResult.push(nestedResult);\n        this._parseVisibilityExpression(object, nestingCounter, nestedResult);\n      } else if (raw instanceof Ref) {\n        currentResult.push(raw.toString());\n      }\n    }\n  }\n  async parseMarkedContentProps(contentProperties, resources) {\n    let optionalContent;\n    if (contentProperties instanceof Name) {\n      const properties = resources.get(\"Properties\");\n      optionalContent = properties.get(contentProperties.name);\n    } else if (contentProperties instanceof Dict) {\n      optionalContent = contentProperties;\n    } else {\n      throw new FormatError(\"Optional content properties malformed.\");\n    }\n    const optionalContentType = optionalContent.get(\"Type\")?.name;\n    if (optionalContentType === \"OCG\") {\n      return {\n        type: optionalContentType,\n        id: optionalContent.objId\n      };\n    } else if (optionalContentType === \"OCMD\") {\n      const expression = optionalContent.get(\"VE\");\n      if (Array.isArray(expression)) {\n        const result = [];\n        this._parseVisibilityExpression(expression, 0, result);\n        if (result.length > 0) {\n          return {\n            type: \"OCMD\",\n            expression: result\n          };\n        }\n      }\n      const optionalContentGroups = optionalContent.get(\"OCGs\");\n      if (Array.isArray(optionalContentGroups) || optionalContentGroups instanceof Dict) {\n        const groupIds = [];\n        if (Array.isArray(optionalContentGroups)) {\n          for (const ocg of optionalContentGroups) {\n            groupIds.push(ocg.toString());\n          }\n        } else {\n          groupIds.push(optionalContentGroups.objId);\n        }\n        return {\n          type: optionalContentType,\n          ids: groupIds,\n          policy: optionalContent.get(\"P\") instanceof Name ? optionalContent.get(\"P\").name : null,\n          expression: null\n        };\n      } else if (optionalContentGroups instanceof Ref) {\n        return {\n          type: optionalContentType,\n          id: optionalContentGroups.toString()\n        };\n      }\n    }\n    return null;\n  }\n  getOperatorList({\n    stream,\n    task,\n    resources,\n    operatorList,\n    initialState = null,\n    fallbackFontDict = null\n  }) {\n    resources ||= Dict.empty;\n    initialState ||= new EvalState();\n    if (!operatorList) {\n      throw new Error('getOperatorList: missing \"operatorList\" parameter');\n    }\n    const self = this;\n    const xref = this.xref;\n    let parsingText = false;\n    const localImageCache = new LocalImageCache();\n    const localColorSpaceCache = new LocalColorSpaceCache();\n    const localGStateCache = new LocalGStateCache();\n    const localTilingPatternCache = new LocalTilingPatternCache();\n    const localShadingPatternCache = new Map();\n    const xobjs = resources.get(\"XObject\") || Dict.empty;\n    const patterns = resources.get(\"Pattern\") || Dict.empty;\n    const stateManager = new StateManager(initialState);\n    const preprocessor = new EvaluatorPreprocessor(stream, xref, stateManager);\n    const timeSlotManager = new TimeSlotManager();\n    function closePendingRestoreOPS(argument) {\n      for (let i = 0, ii = preprocessor.savedStatesDepth; i < ii; i++) {\n        operatorList.addOp(OPS.restore, []);\n      }\n    }\n    return new Promise(function promiseBody(resolve, reject) {\n      const next = function (promise) {\n        Promise.all([promise, operatorList.ready]).then(function () {\n          try {\n            promiseBody(resolve, reject);\n          } catch (ex) {\n            reject(ex);\n          }\n        }, reject);\n      };\n      task.ensureNotTerminated();\n      timeSlotManager.reset();\n      const operation = {};\n      let stop, i, ii, cs, name, isValidName;\n      while (!(stop = timeSlotManager.check())) {\n        operation.args = null;\n        if (!preprocessor.read(operation)) {\n          break;\n        }\n        let args = operation.args;\n        let fn = operation.fn;\n        switch (fn | 0) {\n          case OPS.paintXObject:\n            isValidName = args[0] instanceof Name;\n            name = args[0].name;\n            if (isValidName) {\n              const localImage = localImageCache.getByName(name);\n              if (localImage) {\n                operatorList.addImageOps(localImage.fn, localImage.args, localImage.optionalContent);\n                incrementCachedImageMaskCount(localImage);\n                args = null;\n                continue;\n              }\n            }\n            next(new Promise(function (resolveXObject, rejectXObject) {\n              if (!isValidName) {\n                throw new FormatError(\"XObject must be referred to by name.\");\n              }\n              let xobj = xobjs.getRaw(name);\n              if (xobj instanceof Ref) {\n                const localImage = localImageCache.getByRef(xobj) || self._regionalImageCache.getByRef(xobj);\n                if (localImage) {\n                  operatorList.addImageOps(localImage.fn, localImage.args, localImage.optionalContent);\n                  incrementCachedImageMaskCount(localImage);\n                  resolveXObject();\n                  return;\n                }\n                const globalImage = self.globalImageCache.getData(xobj, self.pageIndex);\n                if (globalImage) {\n                  operatorList.addDependency(globalImage.objId);\n                  operatorList.addImageOps(globalImage.fn, globalImage.args, globalImage.optionalContent);\n                  resolveXObject();\n                  return;\n                }\n                xobj = xref.fetch(xobj);\n              }\n              if (!(xobj instanceof BaseStream)) {\n                throw new FormatError(\"XObject should be a stream\");\n              }\n              const type = xobj.dict.get(\"Subtype\");\n              if (!(type instanceof Name)) {\n                throw new FormatError(\"XObject should have a Name subtype\");\n              }\n              if (type.name === \"Form\") {\n                stateManager.save();\n                self.buildFormXObject(resources, xobj, null, operatorList, task, stateManager.state.clone(), localColorSpaceCache).then(function () {\n                  stateManager.restore();\n                  resolveXObject();\n                }, rejectXObject);\n                return;\n              } else if (type.name === \"Image\") {\n                self.buildPaintImageXObject({\n                  resources,\n                  image: xobj,\n                  operatorList,\n                  cacheKey: name,\n                  localImageCache,\n                  localColorSpaceCache\n                }).then(resolveXObject, rejectXObject);\n                return;\n              } else if (type.name === \"PS\") {\n                info(\"Ignored XObject subtype PS\");\n              } else {\n                throw new FormatError(`Unhandled XObject subtype ${type.name}`);\n              }\n              resolveXObject();\n            }).catch(function (reason) {\n              if (reason instanceof AbortException) {\n                return;\n              }\n              if (self.options.ignoreErrors) {\n                warn(`getOperatorList - ignoring XObject: \"${reason}\".`);\n                return;\n              }\n              throw reason;\n            }));\n            return;\n          case OPS.setFont:\n            var fontSize = args[1];\n            next(self.handleSetFont(resources, args, null, operatorList, task, stateManager.state, fallbackFontDict).then(function (loadedName) {\n              operatorList.addDependency(loadedName);\n              operatorList.addOp(OPS.setFont, [loadedName, fontSize]);\n            }));\n            return;\n          case OPS.beginText:\n            parsingText = true;\n            break;\n          case OPS.endText:\n            parsingText = false;\n            break;\n          case OPS.endInlineImage:\n            var cacheKey = args[0].cacheKey;\n            if (cacheKey) {\n              const localImage = localImageCache.getByName(cacheKey);\n              if (localImage) {\n                operatorList.addImageOps(localImage.fn, localImage.args, localImage.optionalContent);\n                incrementCachedImageMaskCount(localImage);\n                args = null;\n                continue;\n              }\n            }\n            next(self.buildPaintImageXObject({\n              resources,\n              image: args[0],\n              isInline: true,\n              operatorList,\n              cacheKey,\n              localImageCache,\n              localColorSpaceCache\n            }));\n            return;\n          case OPS.showText:\n            if (!stateManager.state.font) {\n              self.ensureStateFont(stateManager.state);\n              continue;\n            }\n            args[0] = self.handleText(args[0], stateManager.state);\n            break;\n          case OPS.showSpacedText:\n            if (!stateManager.state.font) {\n              self.ensureStateFont(stateManager.state);\n              continue;\n            }\n            var combinedGlyphs = [];\n            var state = stateManager.state;\n            for (const arrItem of args[0]) {\n              if (typeof arrItem === \"string\") {\n                combinedGlyphs.push(...self.handleText(arrItem, state));\n              } else if (typeof arrItem === \"number\") {\n                combinedGlyphs.push(arrItem);\n              }\n            }\n            args[0] = combinedGlyphs;\n            fn = OPS.showText;\n            break;\n          case OPS.nextLineShowText:\n            if (!stateManager.state.font) {\n              self.ensureStateFont(stateManager.state);\n              continue;\n            }\n            operatorList.addOp(OPS.nextLine);\n            args[0] = self.handleText(args[0], stateManager.state);\n            fn = OPS.showText;\n            break;\n          case OPS.nextLineSetSpacingShowText:\n            if (!stateManager.state.font) {\n              self.ensureStateFont(stateManager.state);\n              continue;\n            }\n            operatorList.addOp(OPS.nextLine);\n            operatorList.addOp(OPS.setWordSpacing, [args.shift()]);\n            operatorList.addOp(OPS.setCharSpacing, [args.shift()]);\n            args[0] = self.handleText(args[0], stateManager.state);\n            fn = OPS.showText;\n            break;\n          case OPS.setTextRenderingMode:\n            stateManager.state.textRenderingMode = args[0];\n            break;\n          case OPS.setFillColorSpace:\n            {\n              const cachedColorSpace = ColorSpace.getCached(args[0], xref, localColorSpaceCache);\n              if (cachedColorSpace) {\n                stateManager.state.fillColorSpace = cachedColorSpace;\n                continue;\n              }\n              next(self.parseColorSpace({\n                cs: args[0],\n                resources,\n                localColorSpaceCache\n              }).then(function (colorSpace) {\n                if (colorSpace) {\n                  stateManager.state.fillColorSpace = colorSpace;\n                }\n              }));\n              return;\n            }\n          case OPS.setStrokeColorSpace:\n            {\n              const cachedColorSpace = ColorSpace.getCached(args[0], xref, localColorSpaceCache);\n              if (cachedColorSpace) {\n                stateManager.state.strokeColorSpace = cachedColorSpace;\n                continue;\n              }\n              next(self.parseColorSpace({\n                cs: args[0],\n                resources,\n                localColorSpaceCache\n              }).then(function (colorSpace) {\n                if (colorSpace) {\n                  stateManager.state.strokeColorSpace = colorSpace;\n                }\n              }));\n              return;\n            }\n          case OPS.setFillColor:\n            cs = stateManager.state.fillColorSpace;\n            args = cs.getRgb(args, 0);\n            fn = OPS.setFillRGBColor;\n            break;\n          case OPS.setStrokeColor:\n            cs = stateManager.state.strokeColorSpace;\n            args = cs.getRgb(args, 0);\n            fn = OPS.setStrokeRGBColor;\n            break;\n          case OPS.setFillGray:\n            stateManager.state.fillColorSpace = ColorSpace.singletons.gray;\n            args = ColorSpace.singletons.gray.getRgb(args, 0);\n            fn = OPS.setFillRGBColor;\n            break;\n          case OPS.setStrokeGray:\n            stateManager.state.strokeColorSpace = ColorSpace.singletons.gray;\n            args = ColorSpace.singletons.gray.getRgb(args, 0);\n            fn = OPS.setStrokeRGBColor;\n            break;\n          case OPS.setFillCMYKColor:\n            stateManager.state.fillColorSpace = ColorSpace.singletons.cmyk;\n            args = ColorSpace.singletons.cmyk.getRgb(args, 0);\n            fn = OPS.setFillRGBColor;\n            break;\n          case OPS.setStrokeCMYKColor:\n            stateManager.state.strokeColorSpace = ColorSpace.singletons.cmyk;\n            args = ColorSpace.singletons.cmyk.getRgb(args, 0);\n            fn = OPS.setStrokeRGBColor;\n            break;\n          case OPS.setFillRGBColor:\n            stateManager.state.fillColorSpace = ColorSpace.singletons.rgb;\n            args = ColorSpace.singletons.rgb.getRgb(args, 0);\n            break;\n          case OPS.setStrokeRGBColor:\n            stateManager.state.strokeColorSpace = ColorSpace.singletons.rgb;\n            args = ColorSpace.singletons.rgb.getRgb(args, 0);\n            break;\n          case OPS.setFillColorN:\n            cs = stateManager.state.fillColorSpace;\n            if (cs.name === \"Pattern\") {\n              next(self.handleColorN(operatorList, OPS.setFillColorN, args, cs, patterns, resources, task, localColorSpaceCache, localTilingPatternCache, localShadingPatternCache));\n              return;\n            }\n            args = cs.getRgb(args, 0);\n            fn = OPS.setFillRGBColor;\n            break;\n          case OPS.setStrokeColorN:\n            cs = stateManager.state.strokeColorSpace;\n            if (cs.name === \"Pattern\") {\n              next(self.handleColorN(operatorList, OPS.setStrokeColorN, args, cs, patterns, resources, task, localColorSpaceCache, localTilingPatternCache, localShadingPatternCache));\n              return;\n            }\n            args = cs.getRgb(args, 0);\n            fn = OPS.setStrokeRGBColor;\n            break;\n          case OPS.shadingFill:\n            var shadingRes = resources.get(\"Shading\");\n            if (!shadingRes) {\n              throw new FormatError(\"No shading resource found\");\n            }\n            var shading = shadingRes.get(args[0].name);\n            if (!shading) {\n              throw new FormatError(\"No shading object found\");\n            }\n            const patternId = self.parseShading({\n              shading,\n              resources,\n              localColorSpaceCache,\n              localShadingPatternCache\n            });\n            args = [patternId];\n            fn = OPS.shadingFill;\n            break;\n          case OPS.setGState:\n            isValidName = args[0] instanceof Name;\n            name = args[0].name;\n            if (isValidName) {\n              const localGStateObj = localGStateCache.getByName(name);\n              if (localGStateObj) {\n                if (localGStateObj.length > 0) {\n                  operatorList.addOp(OPS.setGState, [localGStateObj]);\n                }\n                args = null;\n                continue;\n              }\n            }\n            next(new Promise(function (resolveGState, rejectGState) {\n              if (!isValidName) {\n                throw new FormatError(\"GState must be referred to by name.\");\n              }\n              const extGState = resources.get(\"ExtGState\");\n              if (!(extGState instanceof Dict)) {\n                throw new FormatError(\"ExtGState should be a dictionary.\");\n              }\n              const gState = extGState.get(name);\n              if (!(gState instanceof Dict)) {\n                throw new FormatError(\"GState should be a dictionary.\");\n              }\n              self.setGState({\n                resources,\n                gState,\n                operatorList,\n                cacheKey: name,\n                task,\n                stateManager,\n                localGStateCache,\n                localColorSpaceCache\n              }).then(resolveGState, rejectGState);\n            }).catch(function (reason) {\n              if (reason instanceof AbortException) {\n                return;\n              }\n              if (self.options.ignoreErrors) {\n                warn(`getOperatorList - ignoring ExtGState: \"${reason}\".`);\n                return;\n              }\n              throw reason;\n            }));\n            return;\n          case OPS.moveTo:\n          case OPS.lineTo:\n          case OPS.curveTo:\n          case OPS.curveTo2:\n          case OPS.curveTo3:\n          case OPS.closePath:\n          case OPS.rectangle:\n            self.buildPath(operatorList, fn, args, parsingText);\n            continue;\n          case OPS.markPoint:\n          case OPS.markPointProps:\n          case OPS.beginCompat:\n          case OPS.endCompat:\n            continue;\n          case OPS.beginMarkedContentProps:\n            if (!(args[0] instanceof Name)) {\n              warn(`Expected name for beginMarkedContentProps arg0=${args[0]}`);\n              operatorList.addOp(OPS.beginMarkedContentProps, [\"OC\", null]);\n              continue;\n            }\n            if (args[0].name === \"OC\") {\n              next(self.parseMarkedContentProps(args[1], resources).then(data => {\n                operatorList.addOp(OPS.beginMarkedContentProps, [\"OC\", data]);\n              }).catch(reason => {\n                if (reason instanceof AbortException) {\n                  return;\n                }\n                if (self.options.ignoreErrors) {\n                  warn(`getOperatorList - ignoring beginMarkedContentProps: \"${reason}\".`);\n                  operatorList.addOp(OPS.beginMarkedContentProps, [\"OC\", null]);\n                  return;\n                }\n                throw reason;\n              }));\n              return;\n            }\n            args = [args[0].name, args[1] instanceof Dict ? args[1].get(\"MCID\") : null];\n            break;\n          case OPS.beginMarkedContent:\n          case OPS.endMarkedContent:\n          default:\n            if (args !== null) {\n              for (i = 0, ii = args.length; i < ii; i++) {\n                if (args[i] instanceof Dict) {\n                  break;\n                }\n              }\n              if (i < ii) {\n                warn(\"getOperatorList - ignoring operator: \" + fn);\n                continue;\n              }\n            }\n        }\n        operatorList.addOp(fn, args);\n      }\n      if (stop) {\n        next(deferred);\n        return;\n      }\n      closePendingRestoreOPS();\n      resolve();\n    }).catch(reason => {\n      if (reason instanceof AbortException) {\n        return;\n      }\n      if (this.options.ignoreErrors) {\n        warn(`getOperatorList - ignoring errors during \"${task.name}\" ` + `task: \"${reason}\".`);\n        closePendingRestoreOPS();\n        return;\n      }\n      throw reason;\n    });\n  }\n  getTextContent({\n    stream,\n    task,\n    resources,\n    stateManager = null,\n    includeMarkedContent = false,\n    sink,\n    seenStyles = new Set(),\n    viewBox,\n    markedContentData = null,\n    disableNormalization = false,\n    keepWhiteSpace = false\n  }) {\n    resources ||= Dict.empty;\n    stateManager ||= new StateManager(new TextState());\n    if (includeMarkedContent) {\n      markedContentData ||= {\n        level: 0\n      };\n    }\n    const textContent = {\n      items: [],\n      styles: Object.create(null)\n    };\n    const textContentItem = {\n      initialized: false,\n      str: [],\n      raw: [],\n      totalWidth: 0,\n      totalHeight: 0,\n      width: 0,\n      height: 0,\n      vertical: false,\n      prevTransform: null,\n      textAdvanceScale: 0,\n      spaceInFlowMin: 0,\n      spaceInFlowMax: 0,\n      trackingSpaceMin: Infinity,\n      negativeSpaceMax: -Infinity,\n      notASpace: -Infinity,\n      transform: null,\n      fontName: null,\n      fontData: null,\n      hasEOL: false\n    };\n    const twoLastChars = [\" \", \" \"];\n    let twoLastCharsPos = 0;\n    function saveLastChar(char) {\n      const nextPos = (twoLastCharsPos + 1) % 2;\n      const ret = twoLastChars[twoLastCharsPos] !== \" \" && twoLastChars[nextPos] === \" \";\n      twoLastChars[twoLastCharsPos] = char;\n      twoLastCharsPos = nextPos;\n      return !keepWhiteSpace && ret;\n    }\n    function shouldAddWhitepsace() {\n      return !keepWhiteSpace && twoLastChars[twoLastCharsPos] !== \" \" && twoLastChars[(twoLastCharsPos + 1) % 2] === \" \";\n    }\n    function resetLastChars() {\n      twoLastChars[0] = twoLastChars[1] = \" \";\n      twoLastCharsPos = 0;\n    }\n    const TRACKING_SPACE_FACTOR = 0.102;\n    const NOT_A_SPACE_FACTOR = 0.03;\n    const NEGATIVE_SPACE_FACTOR = -0.2;\n    const SPACE_IN_FLOW_MIN_FACTOR = 0.102;\n    const SPACE_IN_FLOW_MAX_FACTOR = 0.6;\n    const VERTICAL_SHIFT_RATIO = 0.25;\n    const self = this;\n    const xref = this.xref;\n    const showSpacedTextBuffer = [];\n    let xobjs = null;\n    const emptyXObjectCache = new LocalImageCache();\n    const emptyGStateCache = new LocalGStateCache();\n    const preprocessor = new EvaluatorPreprocessor(stream, xref, stateManager);\n    let textState;\n    function pushWhitespace({\n      width = 0,\n      height = 0,\n      transform = textContentItem.prevTransform,\n      fontName = textContentItem.fontName\n    }) {\n      textContent.items.push({\n        str: \" \",\n        dir: \"ltr\",\n        width,\n        height,\n        transform,\n        fontName,\n        hasEOL: false\n      });\n    }\n    function getCurrentTextTransform() {\n      const font = textState.font;\n      const tsm = [textState.fontSize * textState.textHScale, 0, 0, textState.fontSize, 0, textState.textRise];\n      if (font.isType3Font && (textState.fontSize <= 1 || font.isCharBBox) && !isArrayEqual(textState.fontMatrix, FONT_IDENTITY_MATRIX)) {\n        const glyphHeight = font.bbox[3] - font.bbox[1];\n        if (glyphHeight > 0) {\n          tsm[3] *= glyphHeight * textState.fontMatrix[3];\n        }\n      }\n      return Util.transform(textState.ctm, Util.transform(textState.textMatrix, tsm));\n    }\n    function ensureTextContentItem() {\n      if (textContentItem.initialized) {\n        return textContentItem;\n      }\n      const {\n        font,\n        loadedName\n      } = textState;\n      if (!seenStyles.has(loadedName)) {\n        seenStyles.add(loadedName);\n        textContent.styles[loadedName] = {\n          fontFamily: font.fallbackName,\n          fontData: font,\n          ascent: font.ascent,\n          descent: font.descent,\n          vertical: font.vertical\n        };\n        if (self.options.fontExtraProperties && font.systemFontInfo) {\n          const style = textContent.styles[loadedName];\n          style.fontSubstitution = font.systemFontInfo.css;\n          style.fontSubstitutionLoadedName = font.systemFontInfo.loadedName;\n        }\n      }\n      textContentItem.fontName = loadedName;\n      const trm = textContentItem.transform = getCurrentTextTransform();\n      if (!font.vertical) {\n        textContentItem.width = textContentItem.totalWidth = 0;\n        textContentItem.height = textContentItem.totalHeight = Math.hypot(trm[2], trm[3]);\n        textContentItem.vertical = false;\n      } else {\n        textContentItem.width = textContentItem.totalWidth = Math.hypot(trm[0], trm[1]);\n        textContentItem.height = textContentItem.totalHeight = 0;\n        textContentItem.vertical = true;\n      }\n      const scaleLineX = Math.hypot(textState.textLineMatrix[0], textState.textLineMatrix[1]);\n      const scaleCtmX = Math.hypot(textState.ctm[0], textState.ctm[1]);\n      textContentItem.textAdvanceScale = scaleCtmX * scaleLineX;\n      const {\n        fontSize\n      } = textState;\n      textContentItem.trackingSpaceMin = fontSize * TRACKING_SPACE_FACTOR;\n      textContentItem.notASpace = fontSize * NOT_A_SPACE_FACTOR;\n      textContentItem.negativeSpaceMax = fontSize * NEGATIVE_SPACE_FACTOR;\n      textContentItem.spaceInFlowMin = fontSize * SPACE_IN_FLOW_MIN_FACTOR;\n      textContentItem.spaceInFlowMax = fontSize * SPACE_IN_FLOW_MAX_FACTOR;\n      textContentItem.hasEOL = false;\n      textContentItem.initialized = true;\n      return textContentItem;\n    }\n    function updateAdvanceScale() {\n      if (!textContentItem.initialized) {\n        return;\n      }\n      const scaleLineX = Math.hypot(textState.textLineMatrix[0], textState.textLineMatrix[1]);\n      const scaleCtmX = Math.hypot(textState.ctm[0], textState.ctm[1]);\n      const scaleFactor = scaleCtmX * scaleLineX;\n      if (scaleFactor === textContentItem.textAdvanceScale) {\n        return;\n      }\n      if (!textContentItem.vertical) {\n        textContentItem.totalWidth += textContentItem.width * textContentItem.textAdvanceScale;\n        textContentItem.width = 0;\n      } else {\n        textContentItem.totalHeight += textContentItem.height * textContentItem.textAdvanceScale;\n        textContentItem.height = 0;\n      }\n      textContentItem.textAdvanceScale = scaleFactor;\n    }\n    function runBidiTransform(textChunk) {\n      let text = textChunk.str.join(\"\");\n      if (!disableNormalization) {\n        text = normalizeUnicode(text);\n      }\n      const bidiResult = bidi(text, -1, textChunk.vertical);\n      return {\n        str: bidiResult.str,\n        dir: bidiResult.dir,\n        width: Math.abs(textChunk.totalWidth),\n        height: Math.abs(textChunk.totalHeight),\n        x: textChunk.transform[4],\n        y: textChunk.transform[5],\n        transform: textChunk.transform,\n        fontName: textChunk.fontName,\n        hasEOL: textChunk.hasEOL\n      };\n    }\n    async function handleSetFont(fontName, fontRef) {\n      const translated = await self.loadFont(fontName, fontRef, resources);\n      if (translated.font.isType3Font) {\n        try {\n          await translated.loadType3Data(self, resources, task);\n        } catch {}\n      }\n      textState.realFontName = translated.font.name;\n      textState.loadedName = translated.loadedName;\n      textState.font = translated.font;\n      textState.fontMatrix = translated.font.fontMatrix || FONT_IDENTITY_MATRIX;\n    }\n    function applyInverseRotation(x, y, matrix) {\n      const scale = Math.hypot(matrix[0], matrix[1]);\n      return [(matrix[0] * x + matrix[1] * y) / scale, (matrix[2] * x + matrix[3] * y) / scale];\n    }\n    function compareWithLastPosition(glyphWidth) {\n      const currentTransform = getCurrentTextTransform();\n      let posX = currentTransform[4];\n      let posY = currentTransform[5];\n      if (textState.font?.vertical) {\n        if (posX < viewBox[0] || posX > viewBox[2] || posY + glyphWidth < viewBox[1] || posY > viewBox[3]) {\n          return false;\n        }\n      } else if (posX + glyphWidth < viewBox[0] || posX > viewBox[2] || posY < viewBox[1] || posY > viewBox[3]) {\n        return false;\n      }\n      if (!textState.font || !textContentItem.prevTransform) {\n        return true;\n      }\n      let lastPosX = textContentItem.prevTransform[4];\n      let lastPosY = textContentItem.prevTransform[5];\n      if (lastPosX === posX && lastPosY === posY) {\n        return true;\n      }\n      let rotate = -1;\n      if (currentTransform[0] && currentTransform[1] === 0 && currentTransform[2] === 0) {\n        rotate = currentTransform[0] > 0 ? 0 : 180;\n      } else if (currentTransform[1] && currentTransform[0] === 0 && currentTransform[3] === 0) {\n        rotate = currentTransform[1] > 0 ? 90 : 270;\n      }\n      switch (rotate) {\n        case 0:\n          break;\n        case 90:\n          [posX, posY] = [posY, posX];\n          [lastPosX, lastPosY] = [lastPosY, lastPosX];\n          break;\n        case 180:\n          [posX, posY, lastPosX, lastPosY] = [-posX, -posY, -lastPosX, -lastPosY];\n          break;\n        case 270:\n          [posX, posY] = [-posY, -posX];\n          [lastPosX, lastPosY] = [-lastPosY, -lastPosX];\n          break;\n        default:\n          [posX, posY] = applyInverseRotation(posX, posY, currentTransform);\n          [lastPosX, lastPosY] = applyInverseRotation(lastPosX, lastPosY, textContentItem.prevTransform);\n      }\n      if (textState.font.vertical) {\n        const advanceY = (lastPosY - posY) / textContentItem.textAdvanceScale;\n        const advanceX = posX - lastPosX;\n        const textOrientation = Math.sign(textContentItem.height);\n        if (advanceY < textOrientation * textContentItem.negativeSpaceMax) {\n          if (Math.abs(advanceX) > 0.5 * textContentItem.width) {\n            appendEOL();\n            return true;\n          }\n          resetLastChars();\n          flushTextContentItem();\n          return true;\n        }\n        if (Math.abs(advanceX) > textContentItem.width) {\n          appendEOL();\n          return true;\n        }\n        if (advanceY <= textOrientation * textContentItem.trackingSpaceMin) {\n          if (shouldAddWhitepsace()) {\n            resetLastChars();\n            flushTextContentItem();\n            pushWhitespace({\n              height: Math.abs(advanceY)\n            });\n          } else {\n            textContentItem.height += advanceY;\n          }\n        } else if (!addFakeSpaces(advanceY, textContentItem.prevTransform, textOrientation)) {\n          if (textContentItem.str.length === 0) {\n            resetLastChars();\n            pushWhitespace({\n              height: Math.abs(advanceY)\n            });\n          } else {\n            textContentItem.height += advanceY;\n          }\n        }\n        if (Math.abs(advanceX) > textContentItem.width * VERTICAL_SHIFT_RATIO) {\n          flushTextContentItem();\n        }\n        return true;\n      }\n      const advanceX = (posX - lastPosX) / textContentItem.textAdvanceScale;\n      const advanceY = posY - lastPosY;\n      const textOrientation = Math.sign(textContentItem.width);\n      if (advanceX < textOrientation * textContentItem.negativeSpaceMax) {\n        if (Math.abs(advanceY) > 0.5 * textContentItem.height) {\n          appendEOL();\n          return true;\n        }\n        resetLastChars();\n        flushTextContentItem();\n        return true;\n      }\n      if (Math.abs(advanceY) > textContentItem.height) {\n        appendEOL();\n        return true;\n      }\n      if (advanceX <= textOrientation * textContentItem.trackingSpaceMin) {\n        if (shouldAddWhitepsace()) {\n          resetLastChars();\n          flushTextContentItem();\n          pushWhitespace({\n            width: Math.abs(advanceX)\n          });\n        } else {\n          textContentItem.width += advanceX;\n          if (!textContentItem.spacing) {\n            textContentItem.spacing = [];\n          }\n          textContentItem.spacing.push(advanceX);\n        }\n      } else if (!addFakeSpaces(advanceX, textContentItem.prevTransform, textOrientation)) {\n        if (textContentItem.str.length === 0) {\n          resetLastChars();\n          pushWhitespace({\n            width: Math.abs(advanceX)\n          });\n        } else {\n          if (!textContentItem.spacing) {\n            textContentItem.spacing = [];\n          }\n          textContentItem.spacing.push(advanceX);\n          textContentItem.width += advanceX;\n        }\n      }\n      if (Math.abs(advanceY) > textContentItem.height * VERTICAL_SHIFT_RATIO) {\n        flushTextContentItem();\n      }\n      return true;\n    }\n    function buildTextContentItem({\n      chars,\n      extraSpacing\n    }) {\n      const font = textState.font;\n      if (!chars) {\n        const charSpacing = textState.charSpacing + extraSpacing;\n        if (charSpacing) {\n          if (!font.vertical) {\n            textState.translateTextMatrix(charSpacing * textState.textHScale, 0);\n          } else {\n            textState.translateTextMatrix(0, -charSpacing);\n          }\n        }\n        if (keepWhiteSpace) {\n          compareWithLastPosition(0);\n        }\n        return;\n      }\n      const glyphs = font.charsToGlyphs(chars);\n      const scale = textState.fontMatrix[0] * textState.fontSize;\n      function isBuggy(font, glyphUnicode) {\n        if (font.isBuggy) {\n          return true;\n        }\n        if (font.isNotBuggy) {\n          return false;\n        }\n        if (font.name.indexOf('+TT') >= 0) {\n          font.isBuggy = true;\n          font.buggyReason = \"TT? font\";\n          return true;\n        }\n        if (font.type == \"Type1\") {\n          if (font.subtype === \"Type1C\" && font.name.match(/......\\+......_/)) {\n            font.isBuggy = true;\n            font.buggyReason = \"Fontname match usually buggy Type1C name.\";\n            return true;\n          }\n        }\n        for (let key in font._glyphCache) {\n          const glyph = font._glyphCache[key];\n          if (glyph.unicode.charCodeAt(0) < 15) {\n            font.isBuggy = true;\n            font.buggyReason = \"unicode char non printable in map\";\n            return true;\n          }\n          if (glyph.unicode == \"\\u0000\" || glyph.unicode == '\\x00' || glyph.unicode == '\\x01' || glyph.unicode == '\\x02' || glyph.unicode == '\\x03' || glyph.unicode == '\\x04' || glyph.unicode == '\\x05' || glyph.unicode == '\\x06' || glyph.unicode == '\\x07' || glyph.unicode == '\\x08' || glyph.unicode == '\\x09' || glyph.unicode == '\\x0A' || glyph.unicode == '\\x0B' || glyph.unicode == '\\x0C' || glyph.unicode == '\\x0D' || glyph.unicode == '\\x0E' || glyph.unicode == '\\x0F' || glyph.unicode == '\\x10' || glyph.unicode == '\\x11' || glyph.unicode == '\\x12' || glyph.unicode == '\\x13' || glyph.unicode == '\\x14' || glyph.unicode == '\\x15' || glyph.unicode == '\\x16' || glyph.unicode == '\\x17' || glyph.unicode == '\\x18' || glyph.unicode == '\\x19' || glyph.unicode == '\\x1A' || glyph.unicode == '\\x1B' || glyph.unicode == '\\x1C' || glyph.unicode == '\\x1D' || glyph.unicode == '\\x1E' || glyph.unicode == '\\x1F' || glyph.unicode == '\\u0003' || glyph.unicode >= '\\uE000' && glyph.unicode <= '\\uF8FF') {\n            font.isBuggy = true;\n            font.buggyReason = \"unicode char in special value list\";\n            return true;\n          }\n          if (font.subtype == \"Type1C\" && glyph.fontChar >= '\\uE000' && glyph.fontChar <= '\\uF8FF') {\n            font.isBuggy = true;\n            font.buggyReason = \"font char in special value list (private range)\";\n            return true;\n          }\n        }\n        font.isNotBuggy = true;\n        return false;\n      }\n      for (let i = 0, ii = glyphs.length; i < ii; i++) {\n        const glyph = glyphs[i];\n        const glyphUnicode = glyph.unicode;\n        const fontIsBuggy = isBuggy(font, glyphUnicode);\n        const {\n          category\n        } = glyph;\n        if (!fontIsBuggy && category.isInvisibleFormatMark) {\n          continue;\n        }\n        let charSpacing = textState.charSpacing + (i + 1 === ii ? extraSpacing : 0);\n        let glyphWidth = glyph.width;\n        if (font.vertical) {\n          glyphWidth = glyph.vmetric ? glyph.vmetric[0] : -glyphWidth;\n        }\n        let scaledDim = glyphWidth * scale;\n        if (!fontIsBuggy && !keepWhiteSpace && category.isWhitespace) {\n          if (!font.vertical) {\n            charSpacing += scaledDim + textState.wordSpacing;\n            textState.translateTextMatrix(charSpacing * textState.textHScale, 0);\n          } else {\n            charSpacing += -scaledDim + textState.wordSpacing;\n            textState.translateTextMatrix(0, -charSpacing);\n          }\n          saveLastChar(\" \");\n          continue;\n        }\n        if (fontIsBuggy) {\n          const nextPos = (twoLastCharsPos + 1) % 2;\n          if (category.isWhitespace && twoLastChars[twoLastCharsPos] !== \" \" && twoLastChars[nextPos] === \" \" || !category.isWhitespace && twoLastChars[twoLastCharsPos] === \" \" && twoLastChars[nextPos] === \" \") {\n            resetLastChars();\n            flushTextContentItem();\n          }\n        }\n        if (!category.isZeroWidthDiacritic && !compareWithLastPosition(scaledDim)) {\n          if (!font.vertical) {\n            textState.translateTextMatrix(scaledDim * textState.textHScale, 0);\n          } else {\n            textState.translateTextMatrix(0, scaledDim);\n          }\n          continue;\n        }\n        const textChunk = ensureTextContentItem();\n        if (category.isZeroWidthDiacritic) {\n          scaledDim = 0;\n        }\n        if (!font.vertical) {\n          scaledDim *= textState.textHScale;\n          textState.translateTextMatrix(scaledDim, 0);\n          textChunk.width += scaledDim;\n        } else {\n          textState.translateTextMatrix(0, scaledDim);\n          scaledDim = Math.abs(scaledDim);\n          textChunk.height += scaledDim;\n        }\n        if (scaledDim) {\n          textChunk.prevTransform = getCurrentTextTransform();\n        }\n        saveLastChar(glyphUnicode);\n        if (fontIsBuggy) {\n          const _glyphName = font.differences?.[glyph.originalCharCode] || font.defaultEncoding?.[glyph.originalCharCode] || '';\n          textChunk.str.push(`:->|>_${glyph.originalCharCode}_${glyph.fontChar.charCodeAt(0) || glyph.unicode.charCodeAt(0) || 0}@${_glyphName}@<|<-:`);\n        } else {\n          textChunk.str.push(glyphUnicode);\n        }\n        textChunk.raw.push(glyph);\n        if (charSpacing) {\n          if (!font.vertical) {\n            textState.translateTextMatrix(charSpacing * textState.textHScale, 0);\n          } else {\n            textState.translateTextMatrix(0, -charSpacing);\n          }\n        }\n      }\n    }\n    function appendEOL() {\n      resetLastChars();\n      if (textContentItem.initialized) {\n        textContentItem.hasEOL = true;\n        flushTextContentItem();\n      } else {\n        textContent.items.push({\n          str: \"\",\n          dir: \"ltr\",\n          width: 0,\n          height: 0,\n          transform: getCurrentTextTransform(),\n          fontName: textState.loadedName,\n          hasEOL: true\n        });\n      }\n    }\n    function addFakeSpaces(width, transf, textOrientation) {\n      if (textOrientation * textContentItem.spaceInFlowMin <= width && width <= textOrientation * textContentItem.spaceInFlowMax) {\n        if (textContentItem.initialized) {\n          textContentItem.str.push(\" \");\n          textContentItem.raw.push({\n            unicode: \" \",\n            isFakeSpace: true\n          });\n          if (Util.getRotation(transf) % 90 !== 0) {\n            resetLastChars();\n            return false;\n          }\n          textContentItem.width += width;\n          flushTextContentItem();\n          resetLastChars();\n        }\n        return true;\n      }\n      const fontName = textContentItem.fontName;\n      let height = 0;\n      if (textContentItem.vertical) {\n        height = width;\n        width = 0;\n      }\n      flushTextContentItem();\n      resetLastChars();\n      pushWhitespace({\n        width: Math.abs(width),\n        height: Math.abs(height),\n        transform: transf || getCurrentTextTransform(),\n        fontName\n      });\n      return true;\n    }\n    function flushTextContentItem() {\n      if (!textContentItem.initialized || !textContentItem.str) {\n        return;\n      }\n      if (!textContentItem.vertical) {\n        textContentItem.totalWidth += textContentItem.width * textContentItem.textAdvanceScale;\n      } else {\n        textContentItem.totalHeight += textContentItem.height * textContentItem.textAdvanceScale;\n      }\n      textContent.items.push(runBidiTransform(textContentItem));\n      textContentItem.initialized = false;\n      textContentItem.str.length = 0;\n      textContentItem.raw.length = 0;\n    }\n    function enqueueChunk(batch = false) {\n      const length = textContent.items.length;\n      if (length === 0) {\n        return;\n      }\n      if (batch) {\n        return;\n      }\n      sink.enqueue(textContent, length);\n    }\n    const timeSlotManager = new TimeSlotManager();\n    return new Promise(function promiseBody(resolve, reject) {\n      const next = function (promise) {\n        enqueueChunk(true);\n        Promise.all([promise, sink.ready]).then(function () {\n          try {\n            promiseBody(resolve, reject);\n          } catch (ex) {\n            reject(ex);\n          }\n        }, reject);\n      };\n      task.ensureNotTerminated();\n      timeSlotManager.reset();\n      const operation = {};\n      let stop,\n        args = [];\n      while (!(stop = timeSlotManager.check())) {\n        args.length = 0;\n        operation.args = args;\n        if (!preprocessor.read(operation)) {\n          break;\n        }\n        const previousState = textState;\n        textState = stateManager.state;\n        const fn = operation.fn;\n        args = operation.args;\n        switch (fn | 0) {\n          case OPS.setFont:\n            var fontNameArg = args[0].name,\n              fontSizeArg = args[1];\n            if (textState.font && fontNameArg === textState.fontName && fontSizeArg === textState.fontSize) {\n              break;\n            }\n            flushTextContentItem();\n            textState.fontName = fontNameArg;\n            textState.fontSize = fontSizeArg;\n            next(handleSetFont(fontNameArg, null));\n            return;\n          case OPS.setTextRise:\n            textState.textRise = args[0];\n            break;\n          case OPS.setHScale:\n            textState.textHScale = args[0] / 100;\n            break;\n          case OPS.setLeading:\n            textState.leading = args[0];\n            break;\n          case OPS.moveText:\n            textState.translateTextLineMatrix(args[0], args[1]);\n            textState.textMatrix = textState.textLineMatrix.slice();\n            break;\n          case OPS.setLeadingMoveText:\n            textState.leading = -args[1];\n            textState.translateTextLineMatrix(args[0], args[1]);\n            textState.textMatrix = textState.textLineMatrix.slice();\n            break;\n          case OPS.nextLine:\n            textState.carriageReturn();\n            break;\n          case OPS.setTextMatrix:\n            textState.setTextMatrix(args[0], args[1], args[2], args[3], args[4], args[5]);\n            textState.setTextLineMatrix(args[0], args[1], args[2], args[3], args[4], args[5]);\n            updateAdvanceScale();\n            break;\n          case OPS.setCharSpacing:\n            textState.charSpacing = args[0];\n            break;\n          case OPS.setWordSpacing:\n            textState.wordSpacing = args[0];\n            break;\n          case OPS.beginText:\n            textState.textMatrix = IDENTITY_MATRIX.slice();\n            textState.textLineMatrix = IDENTITY_MATRIX.slice();\n            break;\n          case OPS.showSpacedText:\n            if (!stateManager.state.font) {\n              self.ensureStateFont(stateManager.state);\n              continue;\n            }\n            const spaceFactor = (textState.font.vertical ? 1 : -1) * textState.fontSize / 1000;\n            const elements = args[0];\n            for (let i = 0, ii = elements.length; i < ii; i++) {\n              const item = elements[i];\n              if (typeof item === \"string\") {\n                showSpacedTextBuffer.push(item);\n              } else if (typeof item === \"number\" && item !== 0) {\n                const str = showSpacedTextBuffer.join(\"\");\n                showSpacedTextBuffer.length = 0;\n                buildTextContentItem({\n                  chars: str,\n                  extraSpacing: item * spaceFactor\n                });\n              }\n            }\n            if (showSpacedTextBuffer.length > 0) {\n              const str = showSpacedTextBuffer.join(\"\");\n              showSpacedTextBuffer.length = 0;\n              buildTextContentItem({\n                chars: str,\n                extraSpacing: 0\n              });\n            }\n            break;\n          case OPS.showText:\n            if (!stateManager.state.font) {\n              self.ensureStateFont(stateManager.state);\n              continue;\n            }\n            buildTextContentItem({\n              chars: args[0],\n              extraSpacing: 0\n            });\n            break;\n          case OPS.nextLineShowText:\n            if (!stateManager.state.font) {\n              self.ensureStateFont(stateManager.state);\n              continue;\n            }\n            textState.carriageReturn();\n            buildTextContentItem({\n              chars: args[0],\n              extraSpacing: 0\n            });\n            break;\n          case OPS.nextLineSetSpacingShowText:\n            if (!stateManager.state.font) {\n              self.ensureStateFont(stateManager.state);\n              continue;\n            }\n            textState.wordSpacing = args[0];\n            textState.charSpacing = args[1];\n            textState.carriageReturn();\n            buildTextContentItem({\n              chars: args[2],\n              extraSpacing: 0\n            });\n            break;\n          case OPS.paintXObject:\n            flushTextContentItem();\n            if (!xobjs) {\n              xobjs = resources.get(\"XObject\") || Dict.empty;\n            }\n            var isValidName = args[0] instanceof Name;\n            var name = args[0].name;\n            if (isValidName && emptyXObjectCache.getByName(name)) {\n              break;\n            }\n            next(new Promise(function (resolveXObject, rejectXObject) {\n              if (!isValidName) {\n                throw new FormatError(\"XObject must be referred to by name.\");\n              }\n              let xobj = xobjs.getRaw(name);\n              if (xobj instanceof Ref) {\n                if (emptyXObjectCache.getByRef(xobj)) {\n                  resolveXObject();\n                  return;\n                }\n                const globalImage = self.globalImageCache.getData(xobj, self.pageIndex);\n                if (globalImage) {\n                  resolveXObject();\n                  return;\n                }\n                xobj = xref.fetch(xobj);\n              }\n              if (!(xobj instanceof BaseStream)) {\n                throw new FormatError(\"XObject should be a stream\");\n              }\n              const type = xobj.dict.get(\"Subtype\");\n              if (!(type instanceof Name)) {\n                throw new FormatError(\"XObject should have a Name subtype\");\n              }\n              if (type.name !== \"Form\") {\n                emptyXObjectCache.set(name, xobj.dict.objId, true);\n                resolveXObject();\n                return;\n              }\n              const currentState = stateManager.state.clone();\n              const xObjStateManager = new StateManager(currentState);\n              const matrix = xobj.dict.getArray(\"Matrix\");\n              if (Array.isArray(matrix) && matrix.length === 6) {\n                xObjStateManager.transform(matrix);\n              }\n              const sinkWrapper = {\n                enqueueInvoked: false,\n                enqueue(chunk, size) {\n                  this.enqueueInvoked = true;\n                  sink.enqueue(chunk, size);\n                },\n                get desiredSize() {\n                  return sink.desiredSize;\n                },\n                get ready() {\n                  return sink.ready;\n                }\n              };\n              self.getTextContent({\n                stream: xobj,\n                task,\n                resources: xobj.dict.get(\"Resources\") || resources,\n                stateManager: xObjStateManager,\n                includeMarkedContent,\n                sink: sinkWrapper,\n                seenStyles,\n                viewBox,\n                markedContentData,\n                disableNormalization,\n                keepWhiteSpace\n              }).then(function () {\n                if (!sinkWrapper.enqueueInvoked) {\n                  emptyXObjectCache.set(name, xobj.dict.objId, true);\n                }\n                resolveXObject();\n              }, rejectXObject);\n            }).catch(function (reason) {\n              if (reason instanceof AbortException) {\n                return;\n              }\n              if (self.options.ignoreErrors) {\n                warn(`getTextContent - ignoring XObject: \"${reason}\".`);\n                return;\n              }\n              throw reason;\n            }));\n            return;\n          case OPS.setGState:\n            isValidName = args[0] instanceof Name;\n            name = args[0].name;\n            if (isValidName && emptyGStateCache.getByName(name)) {\n              break;\n            }\n            next(new Promise(function (resolveGState, rejectGState) {\n              if (!isValidName) {\n                throw new FormatError(\"GState must be referred to by name.\");\n              }\n              const extGState = resources.get(\"ExtGState\");\n              if (!(extGState instanceof Dict)) {\n                throw new FormatError(\"ExtGState should be a dictionary.\");\n              }\n              const gState = extGState.get(name);\n              if (!(gState instanceof Dict)) {\n                throw new FormatError(\"GState should be a dictionary.\");\n              }\n              const gStateFont = gState.get(\"Font\");\n              if (!gStateFont) {\n                emptyGStateCache.set(name, gState.objId, true);\n                resolveGState();\n                return;\n              }\n              flushTextContentItem();\n              textState.fontName = null;\n              textState.fontSize = gStateFont[1];\n              handleSetFont(null, gStateFont[0]).then(resolveGState, rejectGState);\n            }).catch(function (reason) {\n              if (reason instanceof AbortException) {\n                return;\n              }\n              if (self.options.ignoreErrors) {\n                warn(`getTextContent - ignoring ExtGState: \"${reason}\".`);\n                return;\n              }\n              throw reason;\n            }));\n            return;\n          case OPS.beginMarkedContent:\n            flushTextContentItem();\n            if (includeMarkedContent) {\n              markedContentData.level++;\n              textContent.items.push({\n                type: \"beginMarkedContent\",\n                tag: args[0] instanceof Name ? args[0].name : null\n              });\n            }\n            break;\n          case OPS.beginMarkedContentProps:\n            flushTextContentItem();\n            if (includeMarkedContent) {\n              markedContentData.level++;\n              let mcid = null;\n              if (args[1] instanceof Dict) {\n                mcid = args[1].get(\"MCID\");\n              }\n              textContent.items.push({\n                type: \"beginMarkedContentProps\",\n                id: Number.isInteger(mcid) ? `${self.idFactory.getPageObjId()}_mc${mcid}` : null,\n                tag: args[0] instanceof Name ? args[0].name : null\n              });\n            }\n            break;\n          case OPS.endMarkedContent:\n            flushTextContentItem();\n            if (includeMarkedContent) {\n              if (markedContentData.level === 0) {\n                break;\n              }\n              markedContentData.level--;\n              textContent.items.push({\n                type: \"endMarkedContent\"\n              });\n            }\n            break;\n          case OPS.restore:\n            if (previousState && (previousState.font !== textState.font || previousState.fontSize !== textState.fontSize || previousState.fontName !== textState.fontName)) {\n              flushTextContentItem();\n            }\n            break;\n        }\n        if (textContent.items.length >= sink.desiredSize) {\n          stop = true;\n          break;\n        }\n      }\n      if (stop) {\n        next(deferred);\n        return;\n      }\n      flushTextContentItem();\n      enqueueChunk();\n      resolve();\n    }).catch(reason => {\n      if (reason instanceof AbortException) {\n        return;\n      }\n      if (this.options.ignoreErrors) {\n        warn(`getTextContent - ignoring errors during \"${task.name}\" ` + `task: \"${reason}\".`);\n        flushTextContentItem();\n        enqueueChunk();\n        return;\n      }\n      throw reason;\n    });\n  }\n  async extractDataStructures(dict, properties) {\n    const xref = this.xref;\n    let cidToGidBytes;\n    const toUnicodePromise = this.readToUnicode(properties.toUnicode);\n    if (properties.composite) {\n      const cidSystemInfo = dict.get(\"CIDSystemInfo\");\n      if (cidSystemInfo instanceof Dict) {\n        properties.cidSystemInfo = {\n          registry: stringToPDFString(cidSystemInfo.get(\"Registry\")),\n          ordering: stringToPDFString(cidSystemInfo.get(\"Ordering\")),\n          supplement: cidSystemInfo.get(\"Supplement\")\n        };\n      }\n      try {\n        const cidToGidMap = dict.get(\"CIDToGIDMap\");\n        if (cidToGidMap instanceof BaseStream) {\n          cidToGidBytes = cidToGidMap.getBytes();\n        }\n      } catch (ex) {\n        if (!this.options.ignoreErrors) {\n          throw ex;\n        }\n        warn(`extractDataStructures - ignoring CIDToGIDMap data: \"${ex}\".`);\n      }\n    }\n    const differences = [];\n    let baseEncodingName = null;\n    let encoding;\n    if (dict.has(\"Encoding\")) {\n      encoding = dict.get(\"Encoding\");\n      if (encoding instanceof Dict) {\n        baseEncodingName = encoding.get(\"BaseEncoding\");\n        baseEncodingName = baseEncodingName instanceof Name ? baseEncodingName.name : null;\n        if (encoding.has(\"Differences\")) {\n          const diffEncoding = encoding.get(\"Differences\");\n          let index = 0;\n          for (const entry of diffEncoding) {\n            const data = xref.fetchIfRef(entry);\n            if (typeof data === \"number\") {\n              index = data;\n            } else if (data instanceof Name) {\n              differences[index++] = data.name;\n            } else {\n              throw new FormatError(`Invalid entry in 'Differences' array: ${data}`);\n            }\n          }\n        }\n      } else if (encoding instanceof Name) {\n        baseEncodingName = encoding.name;\n      } else {\n        const msg = \"Encoding is not a Name nor a Dict\";\n        if (!this.options.ignoreErrors) {\n          throw new FormatError(msg);\n        }\n        warn(msg);\n      }\n      if (baseEncodingName !== \"MacRomanEncoding\" && baseEncodingName !== \"MacExpertEncoding\" && baseEncodingName !== \"WinAnsiEncoding\") {\n        baseEncodingName = null;\n      }\n    }\n    const nonEmbeddedFont = !properties.file || properties.isInternalFont,\n      isSymbolsFontName = getSymbolsFonts()[properties.name];\n    if (baseEncodingName && nonEmbeddedFont && isSymbolsFontName) {\n      baseEncodingName = null;\n    }\n    if (baseEncodingName) {\n      properties.defaultEncoding = getEncoding(baseEncodingName);\n    } else {\n      const isSymbolicFont = !!(properties.flags & FontFlags.Symbolic);\n      const isNonsymbolicFont = !!(properties.flags & FontFlags.Nonsymbolic);\n      encoding = StandardEncoding;\n      if (properties.type === \"TrueType\" && !isNonsymbolicFont) {\n        encoding = WinAnsiEncoding;\n      }\n      if (isSymbolicFont || isSymbolsFontName) {\n        encoding = MacRomanEncoding;\n        if (nonEmbeddedFont) {\n          if (/Symbol/i.test(properties.name)) {\n            encoding = SymbolSetEncoding;\n          } else if (/Dingbats/i.test(properties.name)) {\n            encoding = ZapfDingbatsEncoding;\n          } else if (/Wingdings/i.test(properties.name)) {\n            encoding = WinAnsiEncoding;\n          }\n        }\n      }\n      properties.defaultEncoding = encoding;\n    }\n    properties.differences = differences;\n    properties.baseEncodingName = baseEncodingName;\n    properties.hasEncoding = !!baseEncodingName || differences.length > 0;\n    properties.dict = dict;\n    properties.toUnicode = await toUnicodePromise;\n    const builtToUnicode = await this.buildToUnicode(properties);\n    properties.toUnicode = builtToUnicode;\n    if (cidToGidBytes) {\n      properties.cidToGidMap = this.readCidToGidMap(cidToGidBytes, builtToUnicode);\n    }\n    return properties;\n  }\n  _simpleFontToUnicode(properties, forceGlyphs = false) {\n    assert(!properties.composite, \"Must be a simple font.\");\n    const toUnicode = [];\n    const encoding = properties.defaultEncoding.slice();\n    const baseEncodingName = properties.baseEncodingName;\n    const differences = properties.differences;\n    for (const charcode in differences) {\n      const glyphName = differences[charcode];\n      if (glyphName === \".notdef\") {\n        continue;\n      }\n      encoding[charcode] = glyphName;\n    }\n    const glyphsUnicodeMap = getGlyphsUnicode();\n    for (const charcode in encoding) {\n      let glyphName = encoding[charcode];\n      if (glyphName === \"\") {\n        continue;\n      }\n      let unicode = glyphsUnicodeMap[glyphName];\n      if (unicode !== undefined) {\n        toUnicode[charcode] = String.fromCharCode(unicode);\n        continue;\n      }\n      let code = 0;\n      switch (glyphName[0]) {\n        case \"G\":\n          if (glyphName.length === 3) {\n            code = parseInt(glyphName.substring(1), 16);\n          }\n          break;\n        case \"g\":\n          if (glyphName.length === 5) {\n            code = parseInt(glyphName.substring(1), 16);\n          }\n          break;\n        case \"C\":\n        case \"c\":\n          if (glyphName.length >= 3 && glyphName.length <= 4) {\n            const codeStr = glyphName.substring(1);\n            if (forceGlyphs) {\n              code = parseInt(codeStr, 16);\n              break;\n            }\n            code = +codeStr;\n            if (Number.isNaN(code) && Number.isInteger(parseInt(codeStr, 16))) {\n              return this._simpleFontToUnicode(properties, true);\n            }\n          }\n          break;\n        case \"u\":\n          unicode = getUnicodeForGlyph(glyphName, glyphsUnicodeMap);\n          if (unicode !== -1) {\n            code = unicode;\n          }\n          break;\n        default:\n          switch (glyphName) {\n            case \"f_h\":\n            case \"f_t\":\n            case \"T_h\":\n              toUnicode[charcode] = glyphName.replaceAll(\"_\", \"\");\n              continue;\n          }\n          break;\n      }\n      if (code > 0 && code <= 0x10ffff && Number.isInteger(code)) {\n        if (baseEncodingName && code === +charcode) {\n          const baseEncoding = getEncoding(baseEncodingName);\n          if (baseEncoding && (glyphName = baseEncoding[charcode])) {\n            toUnicode[charcode] = String.fromCharCode(glyphsUnicodeMap[glyphName]);\n            continue;\n          }\n        }\n        toUnicode[charcode] = String.fromCodePoint(code);\n      }\n    }\n    return toUnicode;\n  }\n  async buildToUnicode(properties) {\n    properties.hasIncludedToUnicodeMap = properties.toUnicode?.length > 0;\n    if (properties.hasIncludedToUnicodeMap) {\n      if (!properties.composite && properties.hasEncoding) {\n        properties.fallbackToUnicode = this._simpleFontToUnicode(properties);\n      }\n      return properties.toUnicode;\n    }\n    if (!properties.composite) {\n      return new ToUnicodeMap(this._simpleFontToUnicode(properties));\n    }\n    if (properties.composite && (properties.cMap.builtInCMap && !(properties.cMap instanceof IdentityCMap) || properties.cidSystemInfo?.registry === \"Adobe\" && (properties.cidSystemInfo.ordering === \"GB1\" || properties.cidSystemInfo.ordering === \"CNS1\" || properties.cidSystemInfo.ordering === \"Japan1\" || properties.cidSystemInfo.ordering === \"Korea1\"))) {\n      const {\n        registry,\n        ordering\n      } = properties.cidSystemInfo;\n      const ucs2CMapName = Name.get(`${registry}-${ordering}-UCS2`);\n      const ucs2CMap = await CMapFactory.create({\n        encoding: ucs2CMapName,\n        fetchBuiltInCMap: this._fetchBuiltInCMapBound,\n        useCMap: null\n      });\n      const toUnicode = [],\n        buf = [];\n      properties.cMap.forEach(function (charcode, cid) {\n        if (cid > 0xffff) {\n          throw new FormatError(\"Max size of CID is 65,535\");\n        }\n        const ucs2 = ucs2CMap.lookup(cid);\n        if (ucs2) {\n          buf.length = 0;\n          for (let i = 0, ii = ucs2.length; i < ii; i += 2) {\n            buf.push((ucs2.charCodeAt(i) << 8) + ucs2.charCodeAt(i + 1));\n          }\n          toUnicode[charcode] = String.fromCharCode(...buf);\n        }\n      });\n      return new ToUnicodeMap(toUnicode);\n    }\n    return new IdentityToUnicodeMap(properties.firstChar, properties.lastChar);\n  }\n  async readToUnicode(cmapObj) {\n    if (!cmapObj) {\n      return null;\n    }\n    if (cmapObj instanceof Name) {\n      const cmap = await CMapFactory.create({\n        encoding: cmapObj,\n        fetchBuiltInCMap: this._fetchBuiltInCMapBound,\n        useCMap: null\n      });\n      if (cmap instanceof IdentityCMap) {\n        return new IdentityToUnicodeMap(0, 0xffff);\n      }\n      return new ToUnicodeMap(cmap.getMap());\n    }\n    if (cmapObj instanceof BaseStream) {\n      try {\n        const cmap = await CMapFactory.create({\n          encoding: cmapObj,\n          fetchBuiltInCMap: this._fetchBuiltInCMapBound,\n          useCMap: null\n        });\n        if (cmap instanceof IdentityCMap) {\n          return new IdentityToUnicodeMap(0, 0xffff);\n        }\n        const map = new Array(cmap.length);\n        cmap.forEach(function (charCode, token) {\n          if (typeof token === \"number\") {\n            map[charCode] = String.fromCodePoint(token);\n            return;\n          }\n          const str = [];\n          for (let k = 0; k < token.length; k += 2) {\n            const w1 = token.charCodeAt(k) << 8 | token.charCodeAt(k + 1);\n            if ((w1 & 0xf800) !== 0xd800) {\n              str.push(w1);\n              continue;\n            }\n            k += 2;\n            const w2 = token.charCodeAt(k) << 8 | token.charCodeAt(k + 1);\n            str.push(((w1 & 0x3ff) << 10) + (w2 & 0x3ff) + 0x10000);\n          }\n          map[charCode] = String.fromCodePoint(...str);\n        });\n        return new ToUnicodeMap(map);\n      } catch (reason) {\n        if (reason instanceof AbortException) {\n          return null;\n        }\n        if (this.options.ignoreErrors) {\n          warn(`readToUnicode - ignoring ToUnicode data: \"${reason}\".`);\n          return null;\n        }\n        throw reason;\n      }\n    }\n    return null;\n  }\n  readCidToGidMap(glyphsData, toUnicode) {\n    const result = [];\n    for (let j = 0, jj = glyphsData.length; j < jj; j++) {\n      const glyphID = glyphsData[j++] << 8 | glyphsData[j];\n      const code = j >> 1;\n      if (glyphID === 0 && !toUnicode.has(code)) {\n        continue;\n      }\n      result[code] = glyphID;\n    }\n    return result;\n  }\n  extractWidths(dict, descriptor, properties) {\n    const xref = this.xref;\n    let glyphsWidths = [];\n    let defaultWidth = 0;\n    const glyphsVMetrics = [];\n    let defaultVMetrics;\n    let i, ii, j, jj, start, code, widths;\n    if (properties.composite) {\n      defaultWidth = dict.has(\"DW\") ? dict.get(\"DW\") : 1000;\n      widths = dict.get(\"W\");\n      if (widths) {\n        for (i = 0, ii = widths.length; i < ii; i++) {\n          start = xref.fetchIfRef(widths[i++]);\n          code = xref.fetchIfRef(widths[i]);\n          if (Array.isArray(code)) {\n            for (j = 0, jj = code.length; j < jj; j++) {\n              glyphsWidths[start++] = xref.fetchIfRef(code[j]);\n            }\n          } else {\n            const width = xref.fetchIfRef(widths[++i]);\n            for (j = start; j <= code; j++) {\n              glyphsWidths[j] = width;\n            }\n          }\n        }\n      }\n      if (properties.vertical) {\n        let vmetrics = dict.getArray(\"DW2\") || [880, -1000];\n        defaultVMetrics = [vmetrics[1], defaultWidth * 0.5, vmetrics[0]];\n        vmetrics = dict.get(\"W2\");\n        if (vmetrics) {\n          for (i = 0, ii = vmetrics.length; i < ii; i++) {\n            start = xref.fetchIfRef(vmetrics[i++]);\n            code = xref.fetchIfRef(vmetrics[i]);\n            if (Array.isArray(code)) {\n              for (j = 0, jj = code.length; j < jj; j++) {\n                glyphsVMetrics[start++] = [xref.fetchIfRef(code[j++]), xref.fetchIfRef(code[j++]), xref.fetchIfRef(code[j])];\n              }\n            } else {\n              const vmetric = [xref.fetchIfRef(vmetrics[++i]), xref.fetchIfRef(vmetrics[++i]), xref.fetchIfRef(vmetrics[++i])];\n              for (j = start; j <= code; j++) {\n                glyphsVMetrics[j] = vmetric;\n              }\n            }\n          }\n        }\n      }\n    } else {\n      const firstChar = properties.firstChar;\n      widths = dict.get(\"Widths\");\n      if (widths) {\n        j = firstChar;\n        for (i = 0, ii = widths.length; i < ii; i++) {\n          glyphsWidths[j++] = xref.fetchIfRef(widths[i]);\n        }\n        defaultWidth = parseFloat(descriptor.get(\"MissingWidth\")) || 0;\n      } else {\n        const baseFontName = dict.get(\"BaseFont\");\n        if (baseFontName instanceof Name) {\n          const metrics = this.getBaseFontMetrics(baseFontName.name);\n          glyphsWidths = this.buildCharCodeToWidth(metrics.widths, properties);\n          defaultWidth = metrics.defaultWidth;\n        }\n      }\n    }\n    let isMonospace = true;\n    let firstWidth = defaultWidth;\n    for (const glyph in glyphsWidths) {\n      const glyphWidth = glyphsWidths[glyph];\n      if (!glyphWidth) {\n        continue;\n      }\n      if (!firstWidth) {\n        firstWidth = glyphWidth;\n        continue;\n      }\n      if (firstWidth !== glyphWidth) {\n        isMonospace = false;\n        break;\n      }\n    }\n    if (isMonospace) {\n      properties.flags |= FontFlags.FixedPitch;\n    } else {\n      properties.flags &= ~FontFlags.FixedPitch;\n    }\n    properties.defaultWidth = defaultWidth;\n    properties.widths = glyphsWidths;\n    properties.defaultVMetrics = defaultVMetrics;\n    properties.vmetrics = glyphsVMetrics;\n  }\n  isSerifFont(baseFontName) {\n    const fontNameWoStyle = baseFontName.split(\"-\", 1)[0];\n    return fontNameWoStyle in getSerifFonts() || /serif/gi.test(fontNameWoStyle);\n  }\n  getBaseFontMetrics(name) {\n    let defaultWidth = 0;\n    let widths = Object.create(null);\n    let monospace = false;\n    const stdFontMap = getStdFontMap();\n    let lookupName = stdFontMap[name] || name;\n    const Metrics = getMetrics();\n    if (!(lookupName in Metrics)) {\n      lookupName = this.isSerifFont(name) ? \"Times-Roman\" : \"Helvetica\";\n    }\n    const glyphWidths = Metrics[lookupName];\n    if (typeof glyphWidths === \"number\") {\n      defaultWidth = glyphWidths;\n      monospace = true;\n    } else {\n      widths = glyphWidths();\n    }\n    return {\n      defaultWidth,\n      monospace,\n      widths\n    };\n  }\n  buildCharCodeToWidth(widthsByGlyphName, properties) {\n    const widths = Object.create(null);\n    const differences = properties.differences;\n    const encoding = properties.defaultEncoding;\n    for (let charCode = 0; charCode < 256; charCode++) {\n      if (charCode in differences && widthsByGlyphName[differences[charCode]]) {\n        widths[charCode] = widthsByGlyphName[differences[charCode]];\n        continue;\n      }\n      if (charCode in encoding && widthsByGlyphName[encoding[charCode]]) {\n        widths[charCode] = widthsByGlyphName[encoding[charCode]];\n        continue;\n      }\n    }\n    return widths;\n  }\n  preEvaluateFont(dict) {\n    const baseDict = dict;\n    let type = dict.get(\"Subtype\");\n    if (!(type instanceof Name)) {\n      throw new FormatError(\"invalid font Subtype\");\n    }\n    let composite = false;\n    let hash;\n    if (type.name === \"Type0\") {\n      const df = dict.get(\"DescendantFonts\");\n      if (!df) {\n        throw new FormatError(\"Descendant fonts are not specified\");\n      }\n      dict = Array.isArray(df) ? this.xref.fetchIfRef(df[0]) : df;\n      if (!(dict instanceof Dict)) {\n        throw new FormatError(\"Descendant font is not a dictionary.\");\n      }\n      type = dict.get(\"Subtype\");\n      if (!(type instanceof Name)) {\n        throw new FormatError(\"invalid font Subtype\");\n      }\n      composite = true;\n    }\n    const firstChar = dict.get(\"FirstChar\") || 0,\n      lastChar = dict.get(\"LastChar\") || (composite ? 0xffff : 0xff);\n    const descriptor = dict.get(\"FontDescriptor\");\n    const toUnicode = dict.get(\"ToUnicode\") || baseDict.get(\"ToUnicode\");\n    if (descriptor) {\n      hash = new MurmurHash3_64();\n      const encoding = baseDict.getRaw(\"Encoding\");\n      if (encoding instanceof Name) {\n        hash.update(encoding.name);\n      } else if (encoding instanceof Ref) {\n        hash.update(encoding.toString());\n      } else if (encoding instanceof Dict) {\n        for (const entry of encoding.getRawValues()) {\n          if (entry instanceof Name) {\n            hash.update(entry.name);\n          } else if (entry instanceof Ref) {\n            hash.update(entry.toString());\n          } else if (Array.isArray(entry)) {\n            const diffLength = entry.length,\n              diffBuf = new Array(diffLength);\n            for (let j = 0; j < diffLength; j++) {\n              const diffEntry = entry[j];\n              if (diffEntry instanceof Name) {\n                diffBuf[j] = diffEntry.name;\n              } else if (typeof diffEntry === \"number\" || diffEntry instanceof Ref) {\n                diffBuf[j] = diffEntry.toString();\n              }\n            }\n            hash.update(diffBuf.join());\n          }\n        }\n      }\n      hash.update(`${firstChar}-${lastChar}`);\n      if (toUnicode instanceof BaseStream) {\n        const stream = toUnicode.str || toUnicode;\n        const uint8array = stream.buffer ? new Uint8Array(stream.buffer.buffer, 0, stream.bufferLength) : new Uint8Array(stream.bytes.buffer, stream.start, stream.end - stream.start);\n        hash.update(uint8array);\n      } else if (toUnicode instanceof Name) {\n        hash.update(toUnicode.name);\n      }\n      const widths = dict.get(\"Widths\") || baseDict.get(\"Widths\");\n      if (Array.isArray(widths)) {\n        const widthsBuf = [];\n        for (const entry of widths) {\n          if (typeof entry === \"number\" || entry instanceof Ref) {\n            widthsBuf.push(entry.toString());\n          }\n        }\n        hash.update(widthsBuf.join());\n      }\n      if (composite) {\n        hash.update(\"compositeFont\");\n        const compositeWidths = dict.get(\"W\") || baseDict.get(\"W\");\n        if (Array.isArray(compositeWidths)) {\n          const widthsBuf = [];\n          for (const entry of compositeWidths) {\n            if (typeof entry === \"number\" || entry instanceof Ref) {\n              widthsBuf.push(entry.toString());\n            } else if (Array.isArray(entry)) {\n              const subWidthsBuf = [];\n              for (const element of entry) {\n                if (typeof element === \"number\" || element instanceof Ref) {\n                  subWidthsBuf.push(element.toString());\n                }\n              }\n              widthsBuf.push(`[${subWidthsBuf.join()}]`);\n            }\n          }\n          hash.update(widthsBuf.join());\n        }\n        const cidToGidMap = dict.getRaw(\"CIDToGIDMap\") || baseDict.getRaw(\"CIDToGIDMap\");\n        if (cidToGidMap instanceof Name) {\n          hash.update(cidToGidMap.name);\n        } else if (cidToGidMap instanceof Ref) {\n          hash.update(cidToGidMap.toString());\n        } else if (cidToGidMap instanceof BaseStream) {\n          hash.update(cidToGidMap.peekBytes());\n        }\n      }\n    }\n    return {\n      descriptor,\n      dict,\n      baseDict,\n      composite,\n      type: type.name,\n      firstChar,\n      lastChar,\n      toUnicode,\n      hash: hash ? hash.hexdigest() : \"\"\n    };\n  }\n  async translateFont({\n    descriptor,\n    dict,\n    baseDict,\n    composite,\n    type,\n    firstChar,\n    lastChar,\n    toUnicode,\n    cssFontInfo\n  }) {\n    const isType3Font = type === \"Type3\";\n    if (!descriptor) {\n      if (isType3Font) {\n        descriptor = new Dict(null);\n        descriptor.set(\"FontName\", Name.get(type));\n        descriptor.set(\"FontBBox\", dict.getArray(\"FontBBox\") || [0, 0, 0, 0]);\n      } else {\n        let baseFontName = dict.get(\"BaseFont\");\n        if (!(baseFontName instanceof Name)) {\n          throw new FormatError(\"Base font is not specified\");\n        }\n        baseFontName = baseFontName.name.replaceAll(/[,_]/g, \"-\");\n        const metrics = this.getBaseFontMetrics(baseFontName);\n        const fontNameWoStyle = baseFontName.split(\"-\", 1)[0];\n        const flags = (this.isSerifFont(fontNameWoStyle) ? FontFlags.Serif : 0) | (metrics.monospace ? FontFlags.FixedPitch : 0) | (getSymbolsFonts()[fontNameWoStyle] ? FontFlags.Symbolic : FontFlags.Nonsymbolic);\n        const properties = {\n          type,\n          name: baseFontName,\n          loadedName: baseDict.loadedName,\n          systemFontInfo: null,\n          widths: metrics.widths,\n          defaultWidth: metrics.defaultWidth,\n          isSimulatedFlags: true,\n          flags,\n          firstChar,\n          lastChar,\n          toUnicode,\n          xHeight: 0,\n          capHeight: 0,\n          italicAngle: 0,\n          isType3Font\n        };\n        const widths = dict.get(\"Widths\");\n        const standardFontName = getStandardFontName(baseFontName);\n        let file = null;\n        if (standardFontName) {\n          file = await this.fetchStandardFontData(standardFontName);\n          properties.isInternalFont = !!file;\n        }\n        if (!properties.isInternalFont && this.options.useSystemFonts) {\n          properties.systemFontInfo = getFontSubstitution(this.systemFontCache, this.idFactory, this.options.standardFontDataUrl, baseFontName, standardFontName);\n        }\n        const newProperties = await this.extractDataStructures(dict, properties);\n        if (widths) {\n          const glyphWidths = [];\n          let j = firstChar;\n          for (const width of widths) {\n            glyphWidths[j++] = this.xref.fetchIfRef(width);\n          }\n          newProperties.widths = glyphWidths;\n        } else {\n          newProperties.widths = this.buildCharCodeToWidth(metrics.widths, newProperties);\n        }\n        return new Font(baseFontName, file, newProperties);\n      }\n    }\n    let fontName = descriptor.get(\"FontName\");\n    let baseFont = dict.get(\"BaseFont\");\n    if (typeof fontName === \"string\") {\n      fontName = Name.get(fontName);\n    }\n    if (typeof baseFont === \"string\") {\n      baseFont = Name.get(baseFont);\n    }\n    const fontNameStr = fontName?.name;\n    const baseFontStr = baseFont?.name;\n    if (!isType3Font && fontNameStr !== baseFontStr) {\n      info(`The FontDescriptor's FontName is \"${fontNameStr}\" but ` + `should be the same as the Font's BaseFont \"${baseFontStr}\".`);\n      if (fontNameStr && baseFontStr && (baseFontStr.startsWith(fontNameStr) || !isKnownFontName(fontNameStr) && isKnownFontName(baseFontStr))) {\n        fontName = null;\n      }\n    }\n    fontName ||= baseFont;\n    if (!(fontName instanceof Name)) {\n      throw new FormatError(\"invalid font name\");\n    }\n    let fontFile, subtype, length1, length2, length3;\n    try {\n      fontFile = descriptor.get(\"FontFile\", \"FontFile2\", \"FontFile3\");\n    } catch (ex) {\n      if (!this.options.ignoreErrors) {\n        throw ex;\n      }\n      warn(`translateFont - fetching \"${fontName.name}\" font file: \"${ex}\".`);\n      fontFile = new NullStream();\n    }\n    let isInternalFont = false;\n    let glyphScaleFactors = null;\n    let systemFontInfo = null;\n    if (fontFile) {\n      if (fontFile.dict) {\n        const subtypeEntry = fontFile.dict.get(\"Subtype\");\n        if (subtypeEntry instanceof Name) {\n          subtype = subtypeEntry.name;\n        }\n        length1 = fontFile.dict.get(\"Length1\");\n        length2 = fontFile.dict.get(\"Length2\");\n        length3 = fontFile.dict.get(\"Length3\");\n      }\n    } else if (cssFontInfo) {\n      const standardFontName = getXfaFontName(fontName.name);\n      if (standardFontName) {\n        cssFontInfo.fontFamily = `${cssFontInfo.fontFamily}-PdfJS-XFA`;\n        cssFontInfo.metrics = standardFontName.metrics || null;\n        glyphScaleFactors = standardFontName.factors || null;\n        fontFile = await this.fetchStandardFontData(standardFontName.name);\n        isInternalFont = !!fontFile;\n        baseDict = dict = getXfaFontDict(fontName.name);\n        composite = true;\n      }\n    } else if (!isType3Font) {\n      const standardFontName = getStandardFontName(fontName.name);\n      if (standardFontName) {\n        fontFile = await this.fetchStandardFontData(standardFontName);\n        isInternalFont = !!fontFile;\n      }\n      if (!isInternalFont && this.options.useSystemFonts) {\n        systemFontInfo = getFontSubstitution(this.systemFontCache, this.idFactory, this.options.standardFontDataUrl, fontName.name, standardFontName);\n      }\n    }\n    const properties = {\n      type,\n      name: fontName.name,\n      subtype,\n      file: fontFile,\n      length1,\n      length2,\n      length3,\n      isInternalFont,\n      loadedName: baseDict.loadedName,\n      composite,\n      fixedPitch: false,\n      fontMatrix: dict.getArray(\"FontMatrix\") || FONT_IDENTITY_MATRIX,\n      firstChar,\n      lastChar,\n      toUnicode,\n      bbox: descriptor.getArray(\"FontBBox\") || dict.getArray(\"FontBBox\"),\n      ascent: descriptor.get(\"Ascent\"),\n      descent: descriptor.get(\"Descent\"),\n      xHeight: descriptor.get(\"XHeight\") || 0,\n      capHeight: descriptor.get(\"CapHeight\") || 0,\n      flags: descriptor.get(\"Flags\"),\n      italicAngle: descriptor.get(\"ItalicAngle\") || 0,\n      isType3Font,\n      cssFontInfo,\n      scaleFactors: glyphScaleFactors,\n      systemFontInfo\n    };\n    if (composite) {\n      const cidEncoding = baseDict.get(\"Encoding\");\n      if (cidEncoding instanceof Name) {\n        properties.cidEncoding = cidEncoding.name;\n      }\n      const cMap = await CMapFactory.create({\n        encoding: cidEncoding,\n        fetchBuiltInCMap: this._fetchBuiltInCMapBound,\n        useCMap: null\n      });\n      properties.cMap = cMap;\n      properties.vertical = properties.cMap.vertical;\n    }\n    const newProperties = await this.extractDataStructures(dict, properties);\n    this.extractWidths(dict, descriptor, newProperties);\n    return new Font(fontName.name, fontFile, newProperties);\n  }\n  static buildFontPaths(font, glyphs, handler, evaluatorOptions) {\n    function buildPath(fontChar) {\n      const glyphName = `${font.loadedName}_path_${fontChar}`;\n      try {\n        if (font.renderer.hasBuiltPath(fontChar)) {\n          return;\n        }\n        handler.send(\"commonobj\", [glyphName, \"FontPath\", font.renderer.getPathJs(fontChar)]);\n      } catch (reason) {\n        if (evaluatorOptions.ignoreErrors) {\n          warn(`buildFontPaths - ignoring ${glyphName} glyph: \"${reason}\".`);\n          return;\n        }\n        throw reason;\n      }\n    }\n    for (const glyph of glyphs) {\n      buildPath(glyph.fontChar);\n      const accent = glyph.accent;\n      if (accent?.fontChar) {\n        buildPath(accent.fontChar);\n      }\n    }\n  }\n  static get fallbackFontDict() {\n    const dict = new Dict();\n    dict.set(\"BaseFont\", Name.get(\"Helvetica\"));\n    dict.set(\"Type\", Name.get(\"FallbackType\"));\n    dict.set(\"Subtype\", Name.get(\"FallbackType\"));\n    dict.set(\"Encoding\", Name.get(\"WinAnsiEncoding\"));\n    return shadow(this, \"fallbackFontDict\", dict);\n  }\n}\nclass TranslatedFont {\n  constructor({\n    loadedName,\n    font,\n    dict,\n    evaluatorOptions\n  }) {\n    this.loadedName = loadedName;\n    this.font = font;\n    this.dict = dict;\n    this._evaluatorOptions = evaluatorOptions || DefaultPartialEvaluatorOptions;\n    this.type3Loaded = null;\n    this.type3Dependencies = font.isType3Font ? new Set() : null;\n    this.sent = false;\n  }\n  send(handler) {\n    if (this.sent) {\n      return;\n    }\n    this.sent = true;\n    handler.send(\"commonobj\", [this.loadedName, \"Font\", this.font.exportData(this._evaluatorOptions.fontExtraProperties)]);\n  }\n  fallback(handler) {\n    if (!this.font.data) {\n      return;\n    }\n    this.font.disableFontFace = true;\n    PartialEvaluator.buildFontPaths(this.font, this.font.glyphCacheValues, handler, this._evaluatorOptions);\n  }\n  loadType3Data(evaluator, resources, task) {\n    if (this.type3Loaded) {\n      return this.type3Loaded;\n    }\n    if (!this.font.isType3Font) {\n      throw new Error(\"Must be a Type3 font.\");\n    }\n    const type3Evaluator = evaluator.clone({\n      ignoreErrors: false\n    });\n    type3Evaluator.parsingType3Font = true;\n    const type3FontRefs = new RefSet(evaluator.type3FontRefs);\n    if (this.dict.objId && !type3FontRefs.has(this.dict.objId)) {\n      type3FontRefs.put(this.dict.objId);\n    }\n    type3Evaluator.type3FontRefs = type3FontRefs;\n    const translatedFont = this.font,\n      type3Dependencies = this.type3Dependencies;\n    let loadCharProcsPromise = Promise.resolve();\n    const charProcs = this.dict.get(\"CharProcs\");\n    const fontResources = this.dict.get(\"Resources\") || resources;\n    const charProcOperatorList = Object.create(null);\n    const fontBBox = Util.normalizeRect(translatedFont.bbox || [0, 0, 0, 0]),\n      width = fontBBox[2] - fontBBox[0],\n      height = fontBBox[3] - fontBBox[1];\n    const fontBBoxSize = Math.hypot(width, height);\n    for (const key of charProcs.getKeys()) {\n      loadCharProcsPromise = loadCharProcsPromise.then(() => {\n        const glyphStream = charProcs.get(key);\n        const operatorList = new OperatorList();\n        return type3Evaluator.getOperatorList({\n          stream: glyphStream,\n          task,\n          resources: fontResources,\n          operatorList\n        }).then(() => {\n          if (operatorList.fnArray[0] === OPS.setCharWidthAndBounds) {\n            this._removeType3ColorOperators(operatorList, fontBBoxSize);\n          }\n          charProcOperatorList[key] = operatorList.getIR();\n          for (const dependency of operatorList.dependencies) {\n            type3Dependencies.add(dependency);\n          }\n        }).catch(function (reason) {\n          warn(`Type3 font resource \"${key}\" is not available.`);\n          const dummyOperatorList = new OperatorList();\n          charProcOperatorList[key] = dummyOperatorList.getIR();\n        });\n      });\n    }\n    this.type3Loaded = loadCharProcsPromise.then(() => {\n      translatedFont.charProcOperatorList = charProcOperatorList;\n      if (this._bbox) {\n        translatedFont.isCharBBox = true;\n        translatedFont.bbox = this._bbox;\n      }\n    });\n    return this.type3Loaded;\n  }\n  _removeType3ColorOperators(operatorList, fontBBoxSize = NaN) {\n    const charBBox = Util.normalizeRect(operatorList.argsArray[0].slice(2)),\n      width = charBBox[2] - charBBox[0],\n      height = charBBox[3] - charBBox[1];\n    const charBBoxSize = Math.hypot(width, height);\n    if (width === 0 || height === 0) {\n      operatorList.fnArray.splice(0, 1);\n      operatorList.argsArray.splice(0, 1);\n    } else if (fontBBoxSize === 0 || Math.round(charBBoxSize / fontBBoxSize) >= 10) {\n      if (!this._bbox) {\n        this._bbox = [Infinity, Infinity, -Infinity, -Infinity];\n      }\n      this._bbox[0] = Math.min(this._bbox[0], charBBox[0]);\n      this._bbox[1] = Math.min(this._bbox[1], charBBox[1]);\n      this._bbox[2] = Math.max(this._bbox[2], charBBox[2]);\n      this._bbox[3] = Math.max(this._bbox[3], charBBox[3]);\n    }\n    let i = 0,\n      ii = operatorList.length;\n    while (i < ii) {\n      switch (operatorList.fnArray[i]) {\n        case OPS.setCharWidthAndBounds:\n          break;\n        case OPS.setStrokeColorSpace:\n        case OPS.setFillColorSpace:\n        case OPS.setStrokeColor:\n        case OPS.setStrokeColorN:\n        case OPS.setFillColor:\n        case OPS.setFillColorN:\n        case OPS.setStrokeGray:\n        case OPS.setFillGray:\n        case OPS.setStrokeRGBColor:\n        case OPS.setFillRGBColor:\n        case OPS.setStrokeCMYKColor:\n        case OPS.setFillCMYKColor:\n        case OPS.shadingFill:\n        case OPS.setRenderingIntent:\n          operatorList.fnArray.splice(i, 1);\n          operatorList.argsArray.splice(i, 1);\n          ii--;\n          continue;\n        case OPS.setGState:\n          const [gStateObj] = operatorList.argsArray[i];\n          let j = 0,\n            jj = gStateObj.length;\n          while (j < jj) {\n            const [gStateKey] = gStateObj[j];\n            switch (gStateKey) {\n              case \"TR\":\n              case \"TR2\":\n              case \"HT\":\n              case \"BG\":\n              case \"BG2\":\n              case \"UCR\":\n              case \"UCR2\":\n                gStateObj.splice(j, 1);\n                jj--;\n                continue;\n            }\n            j++;\n          }\n          break;\n      }\n      i++;\n    }\n  }\n}\nclass StateManager {\n  constructor(initialState = new EvalState()) {\n    this.state = initialState;\n    this.stateStack = [];\n  }\n  save() {\n    const old = this.state;\n    this.stateStack.push(this.state);\n    this.state = old.clone();\n  }\n  restore() {\n    const prev = this.stateStack.pop();\n    if (prev) {\n      this.state = prev;\n    }\n  }\n  transform(args) {\n    this.state.ctm = Util.transform(this.state.ctm, args);\n  }\n}\nclass TextState {\n  constructor() {\n    this.ctm = new Float32Array(IDENTITY_MATRIX);\n    this.fontName = null;\n    this.fontSize = 0;\n    this.loadedName = null;\n    this.font = null;\n    this.fontMatrix = FONT_IDENTITY_MATRIX;\n    this.textMatrix = IDENTITY_MATRIX.slice();\n    this.textLineMatrix = IDENTITY_MATRIX.slice();\n    this.charSpacing = 0;\n    this.wordSpacing = 0;\n    this.leading = 0;\n    this.textHScale = 1;\n    this.textRise = 0;\n  }\n  setTextMatrix(a, b, c, d, e, f) {\n    const m = this.textMatrix;\n    m[0] = a;\n    m[1] = b;\n    m[2] = c;\n    m[3] = d;\n    m[4] = e;\n    m[5] = f;\n  }\n  setTextLineMatrix(a, b, c, d, e, f) {\n    const m = this.textLineMatrix;\n    m[0] = a;\n    m[1] = b;\n    m[2] = c;\n    m[3] = d;\n    m[4] = e;\n    m[5] = f;\n  }\n  translateTextMatrix(x, y) {\n    const m = this.textMatrix;\n    m[4] = m[0] * x + m[2] * y + m[4];\n    m[5] = m[1] * x + m[3] * y + m[5];\n  }\n  translateTextLineMatrix(x, y) {\n    const m = this.textLineMatrix;\n    m[4] = m[0] * x + m[2] * y + m[4];\n    m[5] = m[1] * x + m[3] * y + m[5];\n  }\n  carriageReturn() {\n    this.translateTextLineMatrix(0, -this.leading);\n    this.textMatrix = this.textLineMatrix.slice();\n  }\n  clone() {\n    const clone = Object.create(this);\n    clone.textMatrix = this.textMatrix.slice();\n    clone.textLineMatrix = this.textLineMatrix.slice();\n    clone.fontMatrix = this.fontMatrix.slice();\n    return clone;\n  }\n}\nclass EvalState {\n  constructor() {\n    this.ctm = new Float32Array(IDENTITY_MATRIX);\n    this.font = null;\n    this.textRenderingMode = TextRenderingMode.FILL;\n    this.fillColorSpace = ColorSpace.singletons.gray;\n    this.strokeColorSpace = ColorSpace.singletons.gray;\n  }\n  clone() {\n    return Object.create(this);\n  }\n}\nclass EvaluatorPreprocessor {\n  static get opMap() {\n    return shadow(this, \"opMap\", Object.assign(Object.create(null), {\n      w: {\n        id: OPS.setLineWidth,\n        numArgs: 1,\n        variableArgs: false\n      },\n      J: {\n        id: OPS.setLineCap,\n        numArgs: 1,\n        variableArgs: false\n      },\n      j: {\n        id: OPS.setLineJoin,\n        numArgs: 1,\n        variableArgs: false\n      },\n      M: {\n        id: OPS.setMiterLimit,\n        numArgs: 1,\n        variableArgs: false\n      },\n      d: {\n        id: OPS.setDash,\n        numArgs: 2,\n        variableArgs: false\n      },\n      ri: {\n        id: OPS.setRenderingIntent,\n        numArgs: 1,\n        variableArgs: false\n      },\n      i: {\n        id: OPS.setFlatness,\n        numArgs: 1,\n        variableArgs: false\n      },\n      gs: {\n        id: OPS.setGState,\n        numArgs: 1,\n        variableArgs: false\n      },\n      q: {\n        id: OPS.save,\n        numArgs: 0,\n        variableArgs: false\n      },\n      Q: {\n        id: OPS.restore,\n        numArgs: 0,\n        variableArgs: false\n      },\n      cm: {\n        id: OPS.transform,\n        numArgs: 6,\n        variableArgs: false\n      },\n      m: {\n        id: OPS.moveTo,\n        numArgs: 2,\n        variableArgs: false\n      },\n      l: {\n        id: OPS.lineTo,\n        numArgs: 2,\n        variableArgs: false\n      },\n      c: {\n        id: OPS.curveTo,\n        numArgs: 6,\n        variableArgs: false\n      },\n      v: {\n        id: OPS.curveTo2,\n        numArgs: 4,\n        variableArgs: false\n      },\n      y: {\n        id: OPS.curveTo3,\n        numArgs: 4,\n        variableArgs: false\n      },\n      h: {\n        id: OPS.closePath,\n        numArgs: 0,\n        variableArgs: false\n      },\n      re: {\n        id: OPS.rectangle,\n        numArgs: 4,\n        variableArgs: false\n      },\n      S: {\n        id: OPS.stroke,\n        numArgs: 0,\n        variableArgs: false\n      },\n      s: {\n        id: OPS.closeStroke,\n        numArgs: 0,\n        variableArgs: false\n      },\n      f: {\n        id: OPS.fill,\n        numArgs: 0,\n        variableArgs: false\n      },\n      F: {\n        id: OPS.fill,\n        numArgs: 0,\n        variableArgs: false\n      },\n      \"f*\": {\n        id: OPS.eoFill,\n        numArgs: 0,\n        variableArgs: false\n      },\n      B: {\n        id: OPS.fillStroke,\n        numArgs: 0,\n        variableArgs: false\n      },\n      \"B*\": {\n        id: OPS.eoFillStroke,\n        numArgs: 0,\n        variableArgs: false\n      },\n      b: {\n        id: OPS.closeFillStroke,\n        numArgs: 0,\n        variableArgs: false\n      },\n      \"b*\": {\n        id: OPS.closeEOFillStroke,\n        numArgs: 0,\n        variableArgs: false\n      },\n      n: {\n        id: OPS.endPath,\n        numArgs: 0,\n        variableArgs: false\n      },\n      W: {\n        id: OPS.clip,\n        numArgs: 0,\n        variableArgs: false\n      },\n      \"W*\": {\n        id: OPS.eoClip,\n        numArgs: 0,\n        variableArgs: false\n      },\n      BT: {\n        id: OPS.beginText,\n        numArgs: 0,\n        variableArgs: false\n      },\n      ET: {\n        id: OPS.endText,\n        numArgs: 0,\n        variableArgs: false\n      },\n      Tc: {\n        id: OPS.setCharSpacing,\n        numArgs: 1,\n        variableArgs: false\n      },\n      Tw: {\n        id: OPS.setWordSpacing,\n        numArgs: 1,\n        variableArgs: false\n      },\n      Tz: {\n        id: OPS.setHScale,\n        numArgs: 1,\n        variableArgs: false\n      },\n      TL: {\n        id: OPS.setLeading,\n        numArgs: 1,\n        variableArgs: false\n      },\n      Tf: {\n        id: OPS.setFont,\n        numArgs: 2,\n        variableArgs: false\n      },\n      Tr: {\n        id: OPS.setTextRenderingMode,\n        numArgs: 1,\n        variableArgs: false\n      },\n      Ts: {\n        id: OPS.setTextRise,\n        numArgs: 1,\n        variableArgs: false\n      },\n      Td: {\n        id: OPS.moveText,\n        numArgs: 2,\n        variableArgs: false\n      },\n      TD: {\n        id: OPS.setLeadingMoveText,\n        numArgs: 2,\n        variableArgs: false\n      },\n      Tm: {\n        id: OPS.setTextMatrix,\n        numArgs: 6,\n        variableArgs: false\n      },\n      \"T*\": {\n        id: OPS.nextLine,\n        numArgs: 0,\n        variableArgs: false\n      },\n      Tj: {\n        id: OPS.showText,\n        numArgs: 1,\n        variableArgs: false\n      },\n      TJ: {\n        id: OPS.showSpacedText,\n        numArgs: 1,\n        variableArgs: false\n      },\n      \"'\": {\n        id: OPS.nextLineShowText,\n        numArgs: 1,\n        variableArgs: false\n      },\n      '\"': {\n        id: OPS.nextLineSetSpacingShowText,\n        numArgs: 3,\n        variableArgs: false\n      },\n      d0: {\n        id: OPS.setCharWidth,\n        numArgs: 2,\n        variableArgs: false\n      },\n      d1: {\n        id: OPS.setCharWidthAndBounds,\n        numArgs: 6,\n        variableArgs: false\n      },\n      CS: {\n        id: OPS.setStrokeColorSpace,\n        numArgs: 1,\n        variableArgs: false\n      },\n      cs: {\n        id: OPS.setFillColorSpace,\n        numArgs: 1,\n        variableArgs: false\n      },\n      SC: {\n        id: OPS.setStrokeColor,\n        numArgs: 4,\n        variableArgs: true\n      },\n      SCN: {\n        id: OPS.setStrokeColorN,\n        numArgs: 33,\n        variableArgs: true\n      },\n      sc: {\n        id: OPS.setFillColor,\n        numArgs: 4,\n        variableArgs: true\n      },\n      scn: {\n        id: OPS.setFillColorN,\n        numArgs: 33,\n        variableArgs: true\n      },\n      G: {\n        id: OPS.setStrokeGray,\n        numArgs: 1,\n        variableArgs: false\n      },\n      g: {\n        id: OPS.setFillGray,\n        numArgs: 1,\n        variableArgs: false\n      },\n      RG: {\n        id: OPS.setStrokeRGBColor,\n        numArgs: 3,\n        variableArgs: false\n      },\n      rg: {\n        id: OPS.setFillRGBColor,\n        numArgs: 3,\n        variableArgs: false\n      },\n      K: {\n        id: OPS.setStrokeCMYKColor,\n        numArgs: 4,\n        variableArgs: false\n      },\n      k: {\n        id: OPS.setFillCMYKColor,\n        numArgs: 4,\n        variableArgs: false\n      },\n      sh: {\n        id: OPS.shadingFill,\n        numArgs: 1,\n        variableArgs: false\n      },\n      BI: {\n        id: OPS.beginInlineImage,\n        numArgs: 0,\n        variableArgs: false\n      },\n      ID: {\n        id: OPS.beginImageData,\n        numArgs: 0,\n        variableArgs: false\n      },\n      EI: {\n        id: OPS.endInlineImage,\n        numArgs: 1,\n        variableArgs: false\n      },\n      Do: {\n        id: OPS.paintXObject,\n        numArgs: 1,\n        variableArgs: false\n      },\n      MP: {\n        id: OPS.markPoint,\n        numArgs: 1,\n        variableArgs: false\n      },\n      DP: {\n        id: OPS.markPointProps,\n        numArgs: 2,\n        variableArgs: false\n      },\n      BMC: {\n        id: OPS.beginMarkedContent,\n        numArgs: 1,\n        variableArgs: false\n      },\n      BDC: {\n        id: OPS.beginMarkedContentProps,\n        numArgs: 2,\n        variableArgs: false\n      },\n      EMC: {\n        id: OPS.endMarkedContent,\n        numArgs: 0,\n        variableArgs: false\n      },\n      BX: {\n        id: OPS.beginCompat,\n        numArgs: 0,\n        variableArgs: false\n      },\n      EX: {\n        id: OPS.endCompat,\n        numArgs: 0,\n        variableArgs: false\n      },\n      BM: null,\n      BD: null,\n      true: null,\n      fa: null,\n      fal: null,\n      fals: null,\n      false: null,\n      nu: null,\n      nul: null,\n      null: null\n    }));\n  }\n  static MAX_INVALID_PATH_OPS = 10;\n  constructor(stream, xref, stateManager = new StateManager()) {\n    this.parser = new Parser({\n      lexer: new Lexer(stream, EvaluatorPreprocessor.opMap),\n      xref\n    });\n    this.stateManager = stateManager;\n    this.nonProcessedArgs = [];\n    this._isPathOp = false;\n    this._numInvalidPathOPS = 0;\n  }\n  get savedStatesDepth() {\n    return this.stateManager.stateStack.length;\n  }\n  read(operation) {\n    let args = operation.args;\n    while (true) {\n      const obj = this.parser.getObj();\n      if (obj instanceof Cmd) {\n        const cmd = obj.cmd;\n        const opSpec = EvaluatorPreprocessor.opMap[cmd];\n        if (!opSpec) {\n          warn(`Unknown command \"${cmd}\".`);\n          continue;\n        }\n        const fn = opSpec.id;\n        const numArgs = opSpec.numArgs;\n        let argsLength = args !== null ? args.length : 0;\n        if (!this._isPathOp) {\n          this._numInvalidPathOPS = 0;\n        }\n        this._isPathOp = fn >= OPS.moveTo && fn <= OPS.endPath;\n        if (!opSpec.variableArgs) {\n          if (argsLength !== numArgs) {\n            const nonProcessedArgs = this.nonProcessedArgs;\n            while (argsLength > numArgs) {\n              nonProcessedArgs.push(args.shift());\n              argsLength--;\n            }\n            while (argsLength < numArgs && nonProcessedArgs.length !== 0) {\n              if (args === null) {\n                args = [];\n              }\n              args.unshift(nonProcessedArgs.pop());\n              argsLength++;\n            }\n          }\n          if (argsLength < numArgs) {\n            const partialMsg = `command ${cmd}: expected ${numArgs} args, ` + `but received ${argsLength} args.`;\n            if (this._isPathOp && ++this._numInvalidPathOPS > EvaluatorPreprocessor.MAX_INVALID_PATH_OPS) {\n              throw new FormatError(`Invalid ${partialMsg}`);\n            }\n            warn(`Skipping ${partialMsg}`);\n            if (args !== null) {\n              args.length = 0;\n            }\n            continue;\n          }\n        } else if (argsLength > numArgs) {\n          info(`Command ${cmd}: expected [0, ${numArgs}] args, ` + `but received ${argsLength} args.`);\n        }\n        this.preprocessCommand(fn, args);\n        operation.fn = fn;\n        operation.args = args;\n        return true;\n      }\n      if (obj === EOF) {\n        return false;\n      }\n      if (obj !== null) {\n        if (args === null) {\n          args = [];\n        }\n        args.push(obj);\n        if (args.length > 33) {\n          throw new FormatError(\"Too many arguments\");\n        }\n      }\n    }\n  }\n  preprocessCommand(fn, args) {\n    switch (fn | 0) {\n      case OPS.save:\n        this.stateManager.save();\n        break;\n      case OPS.restore:\n        this.stateManager.restore();\n        break;\n      case OPS.transform:\n        this.stateManager.transform(args);\n        break;\n    }\n  }\n}\n\n;// ./src/core/default_appearance.js\n\n\n\n\n\n\n\n\nclass DefaultAppearanceEvaluator extends EvaluatorPreprocessor {\n  constructor(str) {\n    super(new StringStream(str));\n  }\n  parse() {\n    const operation = {\n      fn: 0,\n      args: []\n    };\n    const result = {\n      fontSize: 0,\n      fontName: \"\",\n      fontColor: new Uint8ClampedArray(3)\n    };\n    try {\n      while (true) {\n        operation.args.length = 0;\n        if (!this.read(operation)) {\n          break;\n        }\n        if (this.savedStatesDepth !== 0) {\n          continue;\n        }\n        const {\n          fn,\n          args\n        } = operation;\n        switch (fn | 0) {\n          case OPS.setFont:\n            const [fontName, fontSize] = args;\n            if (fontName instanceof Name) {\n              result.fontName = fontName.name;\n            }\n            if (typeof fontSize === \"number\" && fontSize > 0) {\n              result.fontSize = fontSize;\n            }\n            break;\n          case OPS.setFillRGBColor:\n            ColorSpace.singletons.rgb.getRgbItem(args, 0, result.fontColor, 0);\n            break;\n          case OPS.setFillGray:\n            ColorSpace.singletons.gray.getRgbItem(args, 0, result.fontColor, 0);\n            break;\n          case OPS.setFillCMYKColor:\n            ColorSpace.singletons.cmyk.getRgbItem(args, 0, result.fontColor, 0);\n            break;\n        }\n      }\n    } catch (reason) {\n      warn(`parseDefaultAppearance - ignoring errors: \"${reason}\".`);\n    }\n    return result;\n  }\n}\nfunction parseDefaultAppearance(str) {\n  return new DefaultAppearanceEvaluator(str).parse();\n}\nclass AppearanceStreamEvaluator extends EvaluatorPreprocessor {\n  constructor(stream, evaluatorOptions, xref) {\n    super(stream);\n    this.stream = stream;\n    this.evaluatorOptions = evaluatorOptions;\n    this.xref = xref;\n    this.resources = stream.dict?.get(\"Resources\");\n  }\n  parse() {\n    const operation = {\n      fn: 0,\n      args: []\n    };\n    let result = {\n      scaleFactor: 1,\n      fontSize: 0,\n      fontName: \"\",\n      fontColor: new Uint8ClampedArray(3),\n      fillColorSpace: ColorSpace.singletons.gray\n    };\n    let breakLoop = false;\n    const stack = [];\n    try {\n      while (true) {\n        operation.args.length = 0;\n        if (breakLoop || !this.read(operation)) {\n          break;\n        }\n        const {\n          fn,\n          args\n        } = operation;\n        switch (fn | 0) {\n          case OPS.save:\n            stack.push({\n              scaleFactor: result.scaleFactor,\n              fontSize: result.fontSize,\n              fontName: result.fontName,\n              fontColor: result.fontColor.slice(),\n              fillColorSpace: result.fillColorSpace\n            });\n            break;\n          case OPS.restore:\n            result = stack.pop() || result;\n            break;\n          case OPS.setTextMatrix:\n            result.scaleFactor *= Math.hypot(args[0], args[1]);\n            break;\n          case OPS.setFont:\n            const [fontName, fontSize] = args;\n            if (fontName instanceof Name) {\n              result.fontName = fontName.name;\n            }\n            if (typeof fontSize === \"number\" && fontSize > 0) {\n              result.fontSize = fontSize * result.scaleFactor;\n            }\n            break;\n          case OPS.setFillColorSpace:\n            result.fillColorSpace = ColorSpace.parse({\n              cs: args[0],\n              xref: this.xref,\n              resources: this.resources,\n              pdfFunctionFactory: this._pdfFunctionFactory,\n              localColorSpaceCache: this._localColorSpaceCache\n            });\n            break;\n          case OPS.setFillColor:\n            const cs = result.fillColorSpace;\n            cs.getRgbItem(args, 0, result.fontColor, 0);\n            break;\n          case OPS.setFillRGBColor:\n            ColorSpace.singletons.rgb.getRgbItem(args, 0, result.fontColor, 0);\n            break;\n          case OPS.setFillGray:\n            ColorSpace.singletons.gray.getRgbItem(args, 0, result.fontColor, 0);\n            break;\n          case OPS.setFillCMYKColor:\n            ColorSpace.singletons.cmyk.getRgbItem(args, 0, result.fontColor, 0);\n            break;\n          case OPS.showText:\n          case OPS.showSpacedText:\n          case OPS.nextLineShowText:\n          case OPS.nextLineSetSpacingShowText:\n            breakLoop = true;\n            break;\n        }\n      }\n    } catch (reason) {\n      warn(`parseAppearanceStream - ignoring errors: \"${reason}\".`);\n    }\n    this.stream.reset();\n    delete result.scaleFactor;\n    delete result.fillColorSpace;\n    return result;\n  }\n  get _localColorSpaceCache() {\n    return shadow(this, \"_localColorSpaceCache\", new LocalColorSpaceCache());\n  }\n  get _pdfFunctionFactory() {\n    const pdfFunctionFactory = new PDFFunctionFactory({\n      xref: this.xref,\n      isEvalSupported: this.evaluatorOptions.isEvalSupported\n    });\n    return shadow(this, \"_pdfFunctionFactory\", pdfFunctionFactory);\n  }\n}\nfunction parseAppearanceStream(stream, evaluatorOptions, xref) {\n  return new AppearanceStreamEvaluator(stream, evaluatorOptions, xref).parse();\n}\nfunction getPdfColor(color, isFill) {\n  if (color[0] === color[1] && color[1] === color[2]) {\n    const gray = color[0] / 255;\n    return `${numberToString(gray)} ${isFill ? \"g\" : \"G\"}`;\n  }\n  return Array.from(color, c => numberToString(c / 255)).join(\" \") + ` ${isFill ? \"rg\" : \"RG\"}`;\n}\nfunction createDefaultAppearance({\n  fontSize,\n  fontName,\n  fontColor\n}) {\n  return `/${escapePDFName(fontName)} ${fontSize} Tf ${getPdfColor(fontColor, true)}`;\n}\nclass FakeUnicodeFont {\n  constructor(xref, fontFamily) {\n    this.xref = xref;\n    this.widths = null;\n    this.firstChar = Infinity;\n    this.lastChar = -Infinity;\n    this.fontFamily = fontFamily;\n    const canvas = new OffscreenCanvas(1, 1);\n    this.ctxMeasure = canvas.getContext(\"2d\");\n    if (!FakeUnicodeFont._fontNameId) {\n      FakeUnicodeFont._fontNameId = 1;\n    }\n    this.fontName = Name.get(`InvalidPDFjsFont_${fontFamily}_${FakeUnicodeFont._fontNameId++}`);\n  }\n  get fontDescriptorRef() {\n    if (!FakeUnicodeFont._fontDescriptorRef) {\n      const fontDescriptor = new Dict(this.xref);\n      fontDescriptor.set(\"Type\", Name.get(\"FontDescriptor\"));\n      fontDescriptor.set(\"FontName\", this.fontName);\n      fontDescriptor.set(\"FontFamily\", \"MyriadPro Regular\");\n      fontDescriptor.set(\"FontBBox\", [0, 0, 0, 0]);\n      fontDescriptor.set(\"FontStretch\", Name.get(\"Normal\"));\n      fontDescriptor.set(\"FontWeight\", 400);\n      fontDescriptor.set(\"ItalicAngle\", 0);\n      FakeUnicodeFont._fontDescriptorRef = this.xref.getNewPersistentRef(fontDescriptor);\n    }\n    return FakeUnicodeFont._fontDescriptorRef;\n  }\n  get descendantFontRef() {\n    const descendantFont = new Dict(this.xref);\n    descendantFont.set(\"BaseFont\", this.fontName);\n    descendantFont.set(\"Type\", Name.get(\"Font\"));\n    descendantFont.set(\"Subtype\", Name.get(\"CIDFontType0\"));\n    descendantFont.set(\"CIDToGIDMap\", Name.get(\"Identity\"));\n    descendantFont.set(\"FirstChar\", this.firstChar);\n    descendantFont.set(\"LastChar\", this.lastChar);\n    descendantFont.set(\"FontDescriptor\", this.fontDescriptorRef);\n    descendantFont.set(\"DW\", 1000);\n    const widths = [];\n    const chars = [...this.widths.entries()].sort();\n    let currentChar = null;\n    let currentWidths = null;\n    for (const [char, width] of chars) {\n      if (!currentChar) {\n        currentChar = char;\n        currentWidths = [width];\n        continue;\n      }\n      if (char === currentChar + currentWidths.length) {\n        currentWidths.push(width);\n      } else {\n        widths.push(currentChar, currentWidths);\n        currentChar = char;\n        currentWidths = [width];\n      }\n    }\n    if (currentChar) {\n      widths.push(currentChar, currentWidths);\n    }\n    descendantFont.set(\"W\", widths);\n    const cidSystemInfo = new Dict(this.xref);\n    cidSystemInfo.set(\"Ordering\", \"Identity\");\n    cidSystemInfo.set(\"Registry\", \"Adobe\");\n    cidSystemInfo.set(\"Supplement\", 0);\n    descendantFont.set(\"CIDSystemInfo\", cidSystemInfo);\n    return this.xref.getNewPersistentRef(descendantFont);\n  }\n  get baseFontRef() {\n    const baseFont = new Dict(this.xref);\n    baseFont.set(\"BaseFont\", this.fontName);\n    baseFont.set(\"Type\", Name.get(\"Font\"));\n    baseFont.set(\"Subtype\", Name.get(\"Type0\"));\n    baseFont.set(\"Encoding\", Name.get(\"Identity-H\"));\n    baseFont.set(\"DescendantFonts\", [this.descendantFontRef]);\n    baseFont.set(\"ToUnicode\", Name.get(\"Identity-H\"));\n    return this.xref.getNewPersistentRef(baseFont);\n  }\n  get resources() {\n    const resources = new Dict(this.xref);\n    const font = new Dict(this.xref);\n    font.set(this.fontName.name, this.baseFontRef);\n    resources.set(\"Font\", font);\n    return resources;\n  }\n  _createContext() {\n    this.widths = new Map();\n    this.ctxMeasure.font = `1000px ${this.fontFamily}`;\n    return this.ctxMeasure;\n  }\n  createFontResources(text) {\n    const ctx = this._createContext();\n    for (const line of text.split(/\\r\\n?|\\n/)) {\n      for (const char of line.split(\"\")) {\n        const code = char.charCodeAt(0);\n        if (this.widths.has(code)) {\n          continue;\n        }\n        const metrics = ctx.measureText(char);\n        const width = Math.ceil(metrics.width);\n        this.widths.set(code, width);\n        this.firstChar = Math.min(code, this.firstChar);\n        this.lastChar = Math.max(code, this.lastChar);\n      }\n    }\n    return this.resources;\n  }\n  static getFirstPositionInfo(rect, rotation, fontSize) {\n    const [x1, y1, x2, y2] = rect;\n    let w = x2 - x1;\n    let h = y2 - y1;\n    if (rotation % 180 !== 0) {\n      [w, h] = [h, w];\n    }\n    const lineHeight = LINE_FACTOR * fontSize;\n    const lineDescent = LINE_DESCENT_FACTOR * fontSize;\n    return {\n      coords: [0, h + lineDescent - lineHeight],\n      bbox: [0, 0, w, h],\n      matrix: rotation !== 0 ? getRotationMatrix(rotation, h, lineHeight) : undefined\n    };\n  }\n  createAppearance(text, rect, rotation, fontSize, bgColor, strokeAlpha) {\n    const ctx = this._createContext();\n    const lines = [];\n    let maxWidth = -Infinity;\n    for (const line of text.split(/\\r\\n?|\\n/)) {\n      lines.push(line);\n      const lineWidth = ctx.measureText(line).width;\n      maxWidth = Math.max(maxWidth, lineWidth);\n      for (const code of codePointIter(line)) {\n        const char = String.fromCodePoint(code);\n        let width = this.widths.get(code);\n        if (width === undefined) {\n          const metrics = ctx.measureText(char);\n          width = Math.ceil(metrics.width);\n          this.widths.set(code, width);\n          this.firstChar = Math.min(code, this.firstChar);\n          this.lastChar = Math.max(code, this.lastChar);\n        }\n      }\n    }\n    maxWidth *= fontSize / 1000;\n    const [x1, y1, x2, y2] = rect;\n    let w = x2 - x1;\n    let h = y2 - y1;\n    if (rotation % 180 !== 0) {\n      [w, h] = [h, w];\n    }\n    let hscale = 1;\n    if (maxWidth > w) {\n      hscale = w / maxWidth;\n    }\n    let vscale = 1;\n    const lineHeight = LINE_FACTOR * fontSize;\n    const lineDescent = LINE_DESCENT_FACTOR * fontSize;\n    const maxHeight = lineHeight * lines.length;\n    if (maxHeight > h) {\n      vscale = h / maxHeight;\n    }\n    const fscale = Math.min(hscale, vscale);\n    const newFontSize = fontSize * fscale;\n    const buffer = [\"q\", `0 0 ${numberToString(w)} ${numberToString(h)} re W n`, `BT`, `1 0 0 1 0 ${numberToString(h + lineDescent)} Tm 0 Tc ${getPdfColor(bgColor, true)}`, `/${this.fontName.name} ${numberToString(newFontSize)} Tf`];\n    const {\n      resources\n    } = this;\n    strokeAlpha = typeof strokeAlpha === \"number\" && strokeAlpha >= 0 && strokeAlpha <= 1 ? strokeAlpha : 1;\n    if (strokeAlpha !== 1) {\n      buffer.push(\"/R0 gs\");\n      const extGState = new Dict(this.xref);\n      const r0 = new Dict(this.xref);\n      r0.set(\"ca\", strokeAlpha);\n      r0.set(\"CA\", strokeAlpha);\n      r0.set(\"Type\", Name.get(\"ExtGState\"));\n      extGState.set(\"R0\", r0);\n      resources.set(\"ExtGState\", extGState);\n    }\n    const vShift = numberToString(lineHeight);\n    for (const line of lines) {\n      buffer.push(`0 -${vShift} Td <${stringToUTF16HexString(line)}> Tj`);\n    }\n    buffer.push(\"ET\", \"Q\");\n    const appearance = buffer.join(\"\\n\");\n    const appearanceStreamDict = new Dict(this.xref);\n    appearanceStreamDict.set(\"Subtype\", Name.get(\"Form\"));\n    appearanceStreamDict.set(\"Type\", Name.get(\"XObject\"));\n    appearanceStreamDict.set(\"BBox\", [0, 0, w, h]);\n    appearanceStreamDict.set(\"Length\", appearance.length);\n    appearanceStreamDict.set(\"Resources\", resources);\n    if (rotation) {\n      const matrix = getRotationMatrix(rotation, w, h);\n      appearanceStreamDict.set(\"Matrix\", matrix);\n    }\n    const ap = new StringStream(appearance);\n    ap.dict = appearanceStreamDict;\n    return ap;\n  }\n}\n\n;// ./src/core/name_number_tree.js\n\n\nclass NameOrNumberTree {\n  constructor(root, xref, type) {\n    if (this.constructor === NameOrNumberTree) {\n      unreachable(\"Cannot initialize NameOrNumberTree.\");\n    }\n    this.root = root;\n    this.xref = xref;\n    this._type = type;\n  }\n  getAll() {\n    const map = new Map();\n    if (!this.root) {\n      return map;\n    }\n    const xref = this.xref;\n    const processed = new RefSet();\n    processed.put(this.root);\n    const queue = [this.root];\n    while (queue.length > 0) {\n      const obj = xref.fetchIfRef(queue.shift());\n      if (!(obj instanceof Dict)) {\n        continue;\n      }\n      if (obj.has(\"Kids\")) {\n        const kids = obj.get(\"Kids\");\n        if (!Array.isArray(kids)) {\n          continue;\n        }\n        for (const kid of kids) {\n          if (processed.has(kid)) {\n            throw new FormatError(`Duplicate entry in \"${this._type}\" tree.`);\n          }\n          queue.push(kid);\n          processed.put(kid);\n        }\n        continue;\n      }\n      const entries = obj.get(this._type);\n      if (!Array.isArray(entries)) {\n        continue;\n      }\n      for (let i = 0, ii = entries.length; i < ii; i += 2) {\n        map.set(xref.fetchIfRef(entries[i]), xref.fetchIfRef(entries[i + 1]));\n      }\n    }\n    return map;\n  }\n  get(key) {\n    if (!this.root) {\n      return null;\n    }\n    const xref = this.xref;\n    let kidsOrEntries = xref.fetchIfRef(this.root);\n    let loopCount = 0;\n    const MAX_LEVELS = 10;\n    while (kidsOrEntries.has(\"Kids\")) {\n      if (++loopCount > MAX_LEVELS) {\n        warn(`Search depth limit reached for \"${this._type}\" tree.`);\n        return null;\n      }\n      const kids = kidsOrEntries.get(\"Kids\");\n      if (!Array.isArray(kids)) {\n        return null;\n      }\n      let l = 0,\n        r = kids.length - 1;\n      while (l <= r) {\n        const m = l + r >> 1;\n        const kid = xref.fetchIfRef(kids[m]);\n        const limits = kid.get(\"Limits\");\n        if (key < xref.fetchIfRef(limits[0])) {\n          r = m - 1;\n        } else if (key > xref.fetchIfRef(limits[1])) {\n          l = m + 1;\n        } else {\n          kidsOrEntries = kid;\n          break;\n        }\n      }\n      if (l > r) {\n        return null;\n      }\n    }\n    const entries = kidsOrEntries.get(this._type);\n    if (Array.isArray(entries)) {\n      let l = 0,\n        r = entries.length - 2;\n      while (l <= r) {\n        const tmp = l + r >> 1,\n          m = tmp + (tmp & 1);\n        const currentKey = xref.fetchIfRef(entries[m]);\n        if (key < currentKey) {\n          r = m - 2;\n        } else if (key > currentKey) {\n          l = m + 2;\n        } else {\n          return xref.fetchIfRef(entries[m + 1]);\n        }\n      }\n    }\n    return null;\n  }\n}\nclass NameTree extends NameOrNumberTree {\n  constructor(root, xref) {\n    super(root, xref, \"Names\");\n  }\n}\nclass NumberTree extends NameOrNumberTree {\n  constructor(root, xref) {\n    super(root, xref, \"Nums\");\n  }\n}\n\n;// ./src/core/cleanup_helper.js\n\n\n\n\nfunction clearGlobalCaches() {\n  clearPatternCaches();\n  clearPrimitiveCaches();\n  clearUnicodeCaches();\n  JpxImage.cleanup();\n}\n\n;// ./src/core/file_spec.js\n\n\n\nfunction pickPlatformItem(dict) {\n  if (dict.has(\"UF\")) {\n    return dict.get(\"UF\");\n  } else if (dict.has(\"F\")) {\n    return dict.get(\"F\");\n  } else if (dict.has(\"Unix\")) {\n    return dict.get(\"Unix\");\n  } else if (dict.has(\"Mac\")) {\n    return dict.get(\"Mac\");\n  } else if (dict.has(\"DOS\")) {\n    return dict.get(\"DOS\");\n  }\n  return null;\n}\nclass FileSpec {\n  constructor(root, xref) {\n    if (!(root instanceof Dict)) {\n      return;\n    }\n    this.xref = xref;\n    this.root = root;\n    if (root.has(\"FS\")) {\n      this.fs = root.get(\"FS\");\n    }\n    this.description = root.has(\"Desc\") ? stringToPDFString(root.get(\"Desc\")) : \"\";\n    if (root.has(\"RF\")) {\n      warn(\"Related file specifications are not supported\");\n    }\n    this.contentAvailable = true;\n    if (!root.has(\"EF\")) {\n      this.contentAvailable = false;\n      warn(\"Non-embedded file specifications are not supported\");\n    }\n  }\n  get filename() {\n    if (!this._filename && this.root) {\n      const filename = pickPlatformItem(this.root) || \"unnamed\";\n      this._filename = stringToPDFString(filename).replaceAll(\"\\\\\\\\\", \"\\\\\").replaceAll(\"\\\\/\", \"/\").replaceAll(\"\\\\\", \"/\");\n    }\n    return this._filename;\n  }\n  get content() {\n    if (!this.contentAvailable) {\n      return null;\n    }\n    if (!this.contentRef && this.root) {\n      this.contentRef = pickPlatformItem(this.root.get(\"EF\"));\n    }\n    let content = null;\n    if (this.contentRef) {\n      const fileObj = this.xref.fetchIfRef(this.contentRef);\n      if (fileObj instanceof BaseStream) {\n        content = fileObj.getBytes();\n      } else {\n        warn(\"Embedded file specification points to non-existing/invalid content\");\n      }\n    } else {\n      warn(\"Embedded file specification does not have a content\");\n    }\n    return content;\n  }\n  get serializable() {\n    return {\n      filename: this.filename,\n      content: this.content\n    };\n  }\n}\n\n;// ./src/core/xml_parser.js\n\nconst XMLParserErrorCode = {\n  NoError: 0,\n  EndOfDocument: -1,\n  UnterminatedCdat: -2,\n  UnterminatedXmlDeclaration: -3,\n  UnterminatedDoctypeDeclaration: -4,\n  UnterminatedComment: -5,\n  MalformedElement: -6,\n  OutOfMemory: -7,\n  UnterminatedAttributeValue: -8,\n  UnterminatedElement: -9,\n  ElementNeverBegun: -10\n};\nfunction isWhitespace(s, index) {\n  const ch = s[index];\n  return ch === \" \" || ch === \"\\n\" || ch === \"\\r\" || ch === \"\\t\";\n}\nfunction isWhitespaceString(s) {\n  for (let i = 0, ii = s.length; i < ii; i++) {\n    if (!isWhitespace(s, i)) {\n      return false;\n    }\n  }\n  return true;\n}\nclass XMLParserBase {\n  _resolveEntities(s) {\n    return s.replaceAll(/&([^;]+);/g, (all, entity) => {\n      if (entity.substring(0, 2) === \"#x\") {\n        return String.fromCodePoint(parseInt(entity.substring(2), 16));\n      } else if (entity.substring(0, 1) === \"#\") {\n        return String.fromCodePoint(parseInt(entity.substring(1), 10));\n      }\n      switch (entity) {\n        case \"lt\":\n          return \"<\";\n        case \"gt\":\n          return \">\";\n        case \"amp\":\n          return \"&\";\n        case \"quot\":\n          return '\"';\n        case \"apos\":\n          return \"'\";\n      }\n      return this.onResolveEntity(entity);\n    });\n  }\n  _parseContent(s, start) {\n    const attributes = [];\n    let pos = start;\n    function skipWs() {\n      while (pos < s.length && isWhitespace(s, pos)) {\n        ++pos;\n      }\n    }\n    while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== \">\" && s[pos] !== \"/\") {\n      ++pos;\n    }\n    const name = s.substring(start, pos);\n    skipWs();\n    while (pos < s.length && s[pos] !== \">\" && s[pos] !== \"/\" && s[pos] !== \"?\") {\n      skipWs();\n      let attrName = \"\",\n        attrValue = \"\";\n      while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== \"=\") {\n        attrName += s[pos];\n        ++pos;\n      }\n      skipWs();\n      if (s[pos] !== \"=\") {\n        return null;\n      }\n      ++pos;\n      skipWs();\n      const attrEndChar = s[pos];\n      if (attrEndChar !== '\"' && attrEndChar !== \"'\") {\n        return null;\n      }\n      const attrEndIndex = s.indexOf(attrEndChar, ++pos);\n      if (attrEndIndex < 0) {\n        return null;\n      }\n      attrValue = s.substring(pos, attrEndIndex);\n      attributes.push({\n        name: attrName,\n        value: this._resolveEntities(attrValue)\n      });\n      pos = attrEndIndex + 1;\n      skipWs();\n    }\n    return {\n      name,\n      attributes,\n      parsed: pos - start\n    };\n  }\n  _parseProcessingInstruction(s, start) {\n    let pos = start;\n    function skipWs() {\n      while (pos < s.length && isWhitespace(s, pos)) {\n        ++pos;\n      }\n    }\n    while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== \">\" && s[pos] !== \"?\" && s[pos] !== \"/\") {\n      ++pos;\n    }\n    const name = s.substring(start, pos);\n    skipWs();\n    const attrStart = pos;\n    while (pos < s.length && (s[pos] !== \"?\" || s[pos + 1] !== \">\")) {\n      ++pos;\n    }\n    const value = s.substring(attrStart, pos);\n    return {\n      name,\n      value,\n      parsed: pos - start\n    };\n  }\n  parseXml(s) {\n    let i = 0;\n    while (i < s.length) {\n      const ch = s[i];\n      let j = i;\n      if (ch === \"<\") {\n        ++j;\n        const ch2 = s[j];\n        let q;\n        switch (ch2) {\n          case \"/\":\n            ++j;\n            q = s.indexOf(\">\", j);\n            if (q < 0) {\n              this.onError(XMLParserErrorCode.UnterminatedElement);\n              return;\n            }\n            this.onEndElement(s.substring(j, q));\n            j = q + 1;\n            break;\n          case \"?\":\n            ++j;\n            const pi = this._parseProcessingInstruction(s, j);\n            if (s.substring(j + pi.parsed, j + pi.parsed + 2) !== \"?>\") {\n              this.onError(XMLParserErrorCode.UnterminatedXmlDeclaration);\n              return;\n            }\n            this.onPi(pi.name, pi.value);\n            j += pi.parsed + 2;\n            break;\n          case \"!\":\n            if (s.substring(j + 1, j + 3) === \"--\") {\n              q = s.indexOf(\"-->\", j + 3);\n              if (q < 0) {\n                this.onError(XMLParserErrorCode.UnterminatedComment);\n                return;\n              }\n              this.onComment(s.substring(j + 3, q));\n              j = q + 3;\n            } else if (s.substring(j + 1, j + 8) === \"[CDATA[\") {\n              q = s.indexOf(\"]]>\", j + 8);\n              if (q < 0) {\n                this.onError(XMLParserErrorCode.UnterminatedCdat);\n                return;\n              }\n              this.onCdata(s.substring(j + 8, q));\n              j = q + 3;\n            } else if (s.substring(j + 1, j + 8) === \"DOCTYPE\") {\n              const q2 = s.indexOf(\"[\", j + 8);\n              let complexDoctype = false;\n              q = s.indexOf(\">\", j + 8);\n              if (q < 0) {\n                this.onError(XMLParserErrorCode.UnterminatedDoctypeDeclaration);\n                return;\n              }\n              if (q2 > 0 && q > q2) {\n                q = s.indexOf(\"]>\", j + 8);\n                if (q < 0) {\n                  this.onError(XMLParserErrorCode.UnterminatedDoctypeDeclaration);\n                  return;\n                }\n                complexDoctype = true;\n              }\n              const doctypeContent = s.substring(j + 8, q + (complexDoctype ? 1 : 0));\n              this.onDoctype(doctypeContent);\n              j = q + (complexDoctype ? 2 : 1);\n            } else {\n              this.onError(XMLParserErrorCode.MalformedElement);\n              return;\n            }\n            break;\n          default:\n            const content = this._parseContent(s, j);\n            if (content === null) {\n              this.onError(XMLParserErrorCode.MalformedElement);\n              return;\n            }\n            let isClosed = false;\n            if (s.substring(j + content.parsed, j + content.parsed + 2) === \"/>\") {\n              isClosed = true;\n            } else if (s.substring(j + content.parsed, j + content.parsed + 1) !== \">\") {\n              this.onError(XMLParserErrorCode.UnterminatedElement);\n              return;\n            }\n            this.onBeginElement(content.name, content.attributes, isClosed);\n            j += content.parsed + (isClosed ? 2 : 1);\n            break;\n        }\n      } else {\n        while (j < s.length && s[j] !== \"<\") {\n          j++;\n        }\n        const text = s.substring(i, j);\n        this.onText(this._resolveEntities(text));\n      }\n      i = j;\n    }\n  }\n  onResolveEntity(name) {\n    return `&${name};`;\n  }\n  onPi(name, value) {}\n  onComment(text) {}\n  onCdata(text) {}\n  onDoctype(doctypeContent) {}\n  onText(text) {}\n  onBeginElement(name, attributes, isEmpty) {}\n  onEndElement(name) {}\n  onError(code) {}\n}\nclass SimpleDOMNode {\n  constructor(nodeName, nodeValue) {\n    this.nodeName = nodeName;\n    this.nodeValue = nodeValue;\n    Object.defineProperty(this, \"parentNode\", {\n      value: null,\n      writable: true\n    });\n  }\n  get firstChild() {\n    return this.childNodes?.[0];\n  }\n  get nextSibling() {\n    const childNodes = this.parentNode.childNodes;\n    if (!childNodes) {\n      return undefined;\n    }\n    const index = childNodes.indexOf(this);\n    if (index === -1) {\n      return undefined;\n    }\n    return childNodes[index + 1];\n  }\n  get textContent() {\n    if (!this.childNodes) {\n      return this.nodeValue || \"\";\n    }\n    return this.childNodes.map(function (child) {\n      return child.textContent;\n    }).join(\"\");\n  }\n  get children() {\n    return this.childNodes || [];\n  }\n  hasChildNodes() {\n    return this.childNodes?.length > 0;\n  }\n  searchNode(paths, pos) {\n    if (pos >= paths.length) {\n      return this;\n    }\n    const component = paths[pos];\n    if (component.name.startsWith(\"#\") && pos < paths.length - 1) {\n      return this.searchNode(paths, pos + 1);\n    }\n    const stack = [];\n    let node = this;\n    while (true) {\n      if (component.name === node.nodeName) {\n        if (component.pos === 0) {\n          const res = node.searchNode(paths, pos + 1);\n          if (res !== null) {\n            return res;\n          }\n        } else if (stack.length === 0) {\n          return null;\n        } else {\n          const [parent] = stack.pop();\n          let siblingPos = 0;\n          for (const child of parent.childNodes) {\n            if (component.name === child.nodeName) {\n              if (siblingPos === component.pos) {\n                return child.searchNode(paths, pos + 1);\n              }\n              siblingPos++;\n            }\n          }\n          return node.searchNode(paths, pos + 1);\n        }\n      }\n      if (node.childNodes?.length > 0) {\n        stack.push([node, 0]);\n        node = node.childNodes[0];\n      } else if (stack.length === 0) {\n        return null;\n      } else {\n        while (stack.length !== 0) {\n          const [parent, currentPos] = stack.pop();\n          const newPos = currentPos + 1;\n          if (newPos < parent.childNodes.length) {\n            stack.push([parent, newPos]);\n            node = parent.childNodes[newPos];\n            break;\n          }\n        }\n        if (stack.length === 0) {\n          return null;\n        }\n      }\n    }\n  }\n  dump(buffer) {\n    if (this.nodeName === \"#text\") {\n      buffer.push(encodeToXmlString(this.nodeValue));\n      return;\n    }\n    buffer.push(`<${this.nodeName}`);\n    if (this.attributes) {\n      for (const attribute of this.attributes) {\n        buffer.push(` ${attribute.name}=\"${encodeToXmlString(attribute.value)}\"`);\n      }\n    }\n    if (this.hasChildNodes()) {\n      buffer.push(\">\");\n      for (const child of this.childNodes) {\n        child.dump(buffer);\n      }\n      buffer.push(`</${this.nodeName}>`);\n    } else if (this.nodeValue) {\n      buffer.push(`>${encodeToXmlString(this.nodeValue)}</${this.nodeName}>`);\n    } else {\n      buffer.push(\"/>\");\n    }\n  }\n}\nclass SimpleXMLParser extends XMLParserBase {\n  constructor({\n    hasAttributes = false,\n    lowerCaseName = false\n  }) {\n    super();\n    this._currentFragment = null;\n    this._stack = null;\n    this._errorCode = XMLParserErrorCode.NoError;\n    this._hasAttributes = hasAttributes;\n    this._lowerCaseName = lowerCaseName;\n  }\n  parseFromString(data) {\n    this._currentFragment = [];\n    this._stack = [];\n    this._errorCode = XMLParserErrorCode.NoError;\n    this.parseXml(data);\n    if (this._errorCode !== XMLParserErrorCode.NoError) {\n      return undefined;\n    }\n    const [documentElement] = this._currentFragment;\n    if (!documentElement) {\n      return undefined;\n    }\n    return {\n      documentElement\n    };\n  }\n  onText(text) {\n    if (isWhitespaceString(text)) {\n      return;\n    }\n    const node = new SimpleDOMNode(\"#text\", text);\n    this._currentFragment.push(node);\n  }\n  onCdata(text) {\n    const node = new SimpleDOMNode(\"#text\", text);\n    this._currentFragment.push(node);\n  }\n  onBeginElement(name, attributes, isEmpty) {\n    if (this._lowerCaseName) {\n      name = name.toLowerCase();\n    }\n    const node = new SimpleDOMNode(name);\n    node.childNodes = [];\n    if (this._hasAttributes) {\n      node.attributes = attributes;\n    }\n    this._currentFragment.push(node);\n    if (isEmpty) {\n      return;\n    }\n    this._stack.push(this._currentFragment);\n    this._currentFragment = node.childNodes;\n  }\n  onEndElement(name) {\n    this._currentFragment = this._stack.pop() || [];\n    const lastElement = this._currentFragment.at(-1);\n    if (!lastElement) {\n      return null;\n    }\n    for (const childNode of lastElement.childNodes) {\n      childNode.parentNode = lastElement;\n    }\n    return lastElement;\n  }\n  onError(code) {\n    this._errorCode = code;\n  }\n}\n\n;// ./src/core/metadata_parser.js\n\nclass MetadataParser {\n  constructor(data) {\n    data = this._repair(data);\n    const parser = new SimpleXMLParser({\n      lowerCaseName: true\n    });\n    const xmlDocument = parser.parseFromString(data);\n    this._metadataMap = new Map();\n    this._data = data;\n    if (xmlDocument) {\n      this._parse(xmlDocument);\n    }\n  }\n  _repair(data) {\n    return data.replace(/^[^<]+/, \"\").replaceAll(/>\\\\376\\\\377([^<]+)/g, function (all, codes) {\n      const bytes = codes.replaceAll(/\\\\([0-3])([0-7])([0-7])/g, function (code, d1, d2, d3) {\n        return String.fromCharCode(d1 * 64 + d2 * 8 + d3 * 1);\n      }).replaceAll(/&(amp|apos|gt|lt|quot);/g, function (str, name) {\n        switch (name) {\n          case \"amp\":\n            return \"&\";\n          case \"apos\":\n            return \"'\";\n          case \"gt\":\n            return \">\";\n          case \"lt\":\n            return \"<\";\n          case \"quot\":\n            return '\"';\n        }\n        throw new Error(`_repair: ${name} isn't defined.`);\n      });\n      const charBuf = [\">\"];\n      for (let i = 0, ii = bytes.length; i < ii; i += 2) {\n        const code = bytes.charCodeAt(i) * 256 + bytes.charCodeAt(i + 1);\n        if (code >= 32 && code < 127 && code !== 60 && code !== 62 && code !== 38) {\n          charBuf.push(String.fromCharCode(code));\n        } else {\n          charBuf.push(\"&#x\" + (0x10000 + code).toString(16).substring(1) + \";\");\n        }\n      }\n      return charBuf.join(\"\");\n    });\n  }\n  _getSequence(entry) {\n    const name = entry.nodeName;\n    if (name !== \"rdf:bag\" && name !== \"rdf:seq\" && name !== \"rdf:alt\") {\n      return null;\n    }\n    return entry.childNodes.filter(node => node.nodeName === \"rdf:li\");\n  }\n  _parseArray(entry) {\n    if (!entry.hasChildNodes()) {\n      return;\n    }\n    const [seqNode] = entry.childNodes;\n    const sequence = this._getSequence(seqNode) || [];\n    this._metadataMap.set(entry.nodeName, sequence.map(node => node.textContent.trim()));\n  }\n  _parse(xmlDocument) {\n    let rdf = xmlDocument.documentElement;\n    if (rdf.nodeName !== \"rdf:rdf\") {\n      rdf = rdf.firstChild;\n      while (rdf && rdf.nodeName !== \"rdf:rdf\") {\n        rdf = rdf.nextSibling;\n      }\n    }\n    if (!rdf || rdf.nodeName !== \"rdf:rdf\" || !rdf.hasChildNodes()) {\n      return;\n    }\n    for (const desc of rdf.childNodes) {\n      if (desc.nodeName !== \"rdf:description\") {\n        continue;\n      }\n      for (const entry of desc.childNodes) {\n        const name = entry.nodeName;\n        switch (name) {\n          case \"#text\":\n            continue;\n          case \"dc:creator\":\n          case \"dc:subject\":\n            this._parseArray(entry);\n            continue;\n        }\n        this._metadataMap.set(name, entry.textContent.trim());\n      }\n    }\n  }\n  get serializable() {\n    return {\n      parsedData: this._metadataMap,\n      rawData: this._data\n    };\n  }\n}\n\n;// ./src/core/decrypt_stream.js\n\nconst chunkSize = 512;\nclass DecryptStream extends DecodeStream {\n  constructor(str, maybeLength, decrypt) {\n    super(maybeLength);\n    this.str = str;\n    this.dict = str.dict;\n    this.decrypt = decrypt;\n    this.nextChunk = null;\n    this.initialized = false;\n  }\n  readBlock() {\n    let chunk;\n    if (this.initialized) {\n      chunk = this.nextChunk;\n    } else {\n      chunk = this.str.getBytes(chunkSize);\n      this.initialized = true;\n    }\n    if (!chunk || chunk.length === 0) {\n      this.eof = true;\n      return;\n    }\n    this.nextChunk = this.str.getBytes(chunkSize);\n    const hasMoreData = this.nextChunk?.length > 0;\n    const decrypt = this.decrypt;\n    chunk = decrypt(chunk, !hasMoreData);\n    const bufferLength = this.bufferLength,\n      newLength = bufferLength + chunk.length,\n      buffer = this.ensureBuffer(newLength);\n    buffer.set(chunk, bufferLength);\n    this.bufferLength = newLength;\n  }\n}\n\n;// ./src/core/crypto.js\n\n\n\nclass ARCFourCipher {\n  constructor(key) {\n    this.a = 0;\n    this.b = 0;\n    const s = new Uint8Array(256);\n    const keyLength = key.length;\n    for (let i = 0; i < 256; ++i) {\n      s[i] = i;\n    }\n    for (let i = 0, j = 0; i < 256; ++i) {\n      const tmp = s[i];\n      j = j + tmp + key[i % keyLength] & 0xff;\n      s[i] = s[j];\n      s[j] = tmp;\n    }\n    this.s = s;\n  }\n  encryptBlock(data) {\n    let a = this.a,\n      b = this.b;\n    const s = this.s;\n    const n = data.length;\n    const output = new Uint8Array(n);\n    for (let i = 0; i < n; ++i) {\n      a = a + 1 & 0xff;\n      const tmp = s[a];\n      b = b + tmp & 0xff;\n      const tmp2 = s[b];\n      s[a] = tmp2;\n      s[b] = tmp;\n      output[i] = data[i] ^ s[tmp + tmp2 & 0xff];\n    }\n    this.a = a;\n    this.b = b;\n    return output;\n  }\n  decryptBlock(data) {\n    return this.encryptBlock(data);\n  }\n  encrypt(data) {\n    return this.encryptBlock(data);\n  }\n}\nconst calculateMD5 = function calculateMD5Closure() {\n  const r = new Uint8Array([7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]);\n  const k = new Int32Array([-680876936, -389564586, 606105819, -1044525330, -176418897, 1200080426, -1473231341, -45705983, 1770035416, -1958414417, -42063, -1990404162, 1804603682, -40341101, -1502002290, 1236535329, -165796510, -1069501632, 643717713, -373897302, -701558691, 38016083, -660478335, -405537848, 568446438, -1019803690, -187363961, 1163531501, -1444681467, -51403784, 1735328473, -1926607734, -378558, -2022574463, 1839030562, -35309556, -1530992060, 1272893353, -155497632, -1094730640, 681279174, -358537222, -722521979, 76029189, -640364487, -421815835, 530742520, -995338651, -198630844, 1126891415, -1416354905, -57434055, 1700485571, -1894986606, -1051523, -2054922799, 1873313359, -30611744, -1560198380, 1309151649, -145523070, -1120210379, 718787259, -343485551]);\n  function hash(data, offset, length) {\n    let h0 = 1732584193,\n      h1 = -271733879,\n      h2 = -1732584194,\n      h3 = 271733878;\n    const paddedLength = length + 72 & ~63;\n    const padded = new Uint8Array(paddedLength);\n    let i, j;\n    for (i = 0; i < length; ++i) {\n      padded[i] = data[offset++];\n    }\n    padded[i++] = 0x80;\n    const n = paddedLength - 8;\n    while (i < n) {\n      padded[i++] = 0;\n    }\n    padded[i++] = length << 3 & 0xff;\n    padded[i++] = length >> 5 & 0xff;\n    padded[i++] = length >> 13 & 0xff;\n    padded[i++] = length >> 21 & 0xff;\n    padded[i++] = length >>> 29 & 0xff;\n    padded[i++] = 0;\n    padded[i++] = 0;\n    padded[i++] = 0;\n    const w = new Int32Array(16);\n    for (i = 0; i < paddedLength;) {\n      for (j = 0; j < 16; ++j, i += 4) {\n        w[j] = padded[i] | padded[i + 1] << 8 | padded[i + 2] << 16 | padded[i + 3] << 24;\n      }\n      let a = h0,\n        b = h1,\n        c = h2,\n        d = h3,\n        f,\n        g;\n      for (j = 0; j < 64; ++j) {\n        if (j < 16) {\n          f = b & c | ~b & d;\n          g = j;\n        } else if (j < 32) {\n          f = d & b | ~d & c;\n          g = 5 * j + 1 & 15;\n        } else if (j < 48) {\n          f = b ^ c ^ d;\n          g = 3 * j + 5 & 15;\n        } else {\n          f = c ^ (b | ~d);\n          g = 7 * j & 15;\n        }\n        const tmp = d,\n          rotateArg = a + f + k[j] + w[g] | 0,\n          rotate = r[j];\n        d = c;\n        c = b;\n        b = b + (rotateArg << rotate | rotateArg >>> 32 - rotate) | 0;\n        a = tmp;\n      }\n      h0 = h0 + a | 0;\n      h1 = h1 + b | 0;\n      h2 = h2 + c | 0;\n      h3 = h3 + d | 0;\n    }\n    return new Uint8Array([h0 & 0xFF, h0 >> 8 & 0xFF, h0 >> 16 & 0xFF, h0 >>> 24 & 0xFF, h1 & 0xFF, h1 >> 8 & 0xFF, h1 >> 16 & 0xFF, h1 >>> 24 & 0xFF, h2 & 0xFF, h2 >> 8 & 0xFF, h2 >> 16 & 0xFF, h2 >>> 24 & 0xFF, h3 & 0xFF, h3 >> 8 & 0xFF, h3 >> 16 & 0xFF, h3 >>> 24 & 0xFF]);\n  }\n  return hash;\n}();\nclass Word64 {\n  constructor(highInteger, lowInteger) {\n    this.high = highInteger | 0;\n    this.low = lowInteger | 0;\n  }\n  and(word) {\n    this.high &= word.high;\n    this.low &= word.low;\n  }\n  xor(word) {\n    this.high ^= word.high;\n    this.low ^= word.low;\n  }\n  or(word) {\n    this.high |= word.high;\n    this.low |= word.low;\n  }\n  shiftRight(places) {\n    if (places >= 32) {\n      this.low = this.high >>> places - 32 | 0;\n      this.high = 0;\n    } else {\n      this.low = this.low >>> places | this.high << 32 - places;\n      this.high = this.high >>> places | 0;\n    }\n  }\n  shiftLeft(places) {\n    if (places >= 32) {\n      this.high = this.low << places - 32;\n      this.low = 0;\n    } else {\n      this.high = this.high << places | this.low >>> 32 - places;\n      this.low <<= places;\n    }\n  }\n  rotateRight(places) {\n    let low, high;\n    if (places & 32) {\n      high = this.low;\n      low = this.high;\n    } else {\n      low = this.low;\n      high = this.high;\n    }\n    places &= 31;\n    this.low = low >>> places | high << 32 - places;\n    this.high = high >>> places | low << 32 - places;\n  }\n  not() {\n    this.high = ~this.high;\n    this.low = ~this.low;\n  }\n  add(word) {\n    const lowAdd = (this.low >>> 0) + (word.low >>> 0);\n    let highAdd = (this.high >>> 0) + (word.high >>> 0);\n    if (lowAdd > 0xffffffff) {\n      highAdd += 1;\n    }\n    this.low = lowAdd | 0;\n    this.high = highAdd | 0;\n  }\n  copyTo(bytes, offset) {\n    bytes[offset] = this.high >>> 24 & 0xff;\n    bytes[offset + 1] = this.high >> 16 & 0xff;\n    bytes[offset + 2] = this.high >> 8 & 0xff;\n    bytes[offset + 3] = this.high & 0xff;\n    bytes[offset + 4] = this.low >>> 24 & 0xff;\n    bytes[offset + 5] = this.low >> 16 & 0xff;\n    bytes[offset + 6] = this.low >> 8 & 0xff;\n    bytes[offset + 7] = this.low & 0xff;\n  }\n  assign(word) {\n    this.high = word.high;\n    this.low = word.low;\n  }\n}\nconst calculateSHA256 = function calculateSHA256Closure() {\n  function rotr(x, n) {\n    return x >>> n | x << 32 - n;\n  }\n  function ch(x, y, z) {\n    return x & y ^ ~x & z;\n  }\n  function maj(x, y, z) {\n    return x & y ^ x & z ^ y & z;\n  }\n  function sigma(x) {\n    return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22);\n  }\n  function sigmaPrime(x) {\n    return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25);\n  }\n  function littleSigma(x) {\n    return rotr(x, 7) ^ rotr(x, 18) ^ x >>> 3;\n  }\n  function littleSigmaPrime(x) {\n    return rotr(x, 17) ^ rotr(x, 19) ^ x >>> 10;\n  }\n  const k = [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];\n  function hash(data, offset, length) {\n    let h0 = 0x6a09e667,\n      h1 = 0xbb67ae85,\n      h2 = 0x3c6ef372,\n      h3 = 0xa54ff53a,\n      h4 = 0x510e527f,\n      h5 = 0x9b05688c,\n      h6 = 0x1f83d9ab,\n      h7 = 0x5be0cd19;\n    const paddedLength = Math.ceil((length + 9) / 64) * 64;\n    const padded = new Uint8Array(paddedLength);\n    let i, j;\n    for (i = 0; i < length; ++i) {\n      padded[i] = data[offset++];\n    }\n    padded[i++] = 0x80;\n    const n = paddedLength - 8;\n    while (i < n) {\n      padded[i++] = 0;\n    }\n    padded[i++] = 0;\n    padded[i++] = 0;\n    padded[i++] = 0;\n    padded[i++] = length >>> 29 & 0xff;\n    padded[i++] = length >> 21 & 0xff;\n    padded[i++] = length >> 13 & 0xff;\n    padded[i++] = length >> 5 & 0xff;\n    padded[i++] = length << 3 & 0xff;\n    const w = new Uint32Array(64);\n    for (i = 0; i < paddedLength;) {\n      for (j = 0; j < 16; ++j) {\n        w[j] = padded[i] << 24 | padded[i + 1] << 16 | padded[i + 2] << 8 | padded[i + 3];\n        i += 4;\n      }\n      for (j = 16; j < 64; ++j) {\n        w[j] = littleSigmaPrime(w[j - 2]) + w[j - 7] + littleSigma(w[j - 15]) + w[j - 16] | 0;\n      }\n      let a = h0,\n        b = h1,\n        c = h2,\n        d = h3,\n        e = h4,\n        f = h5,\n        g = h6,\n        h = h7,\n        t1,\n        t2;\n      for (j = 0; j < 64; ++j) {\n        t1 = h + sigmaPrime(e) + ch(e, f, g) + k[j] + w[j];\n        t2 = sigma(a) + maj(a, b, c);\n        h = g;\n        g = f;\n        f = e;\n        e = d + t1 | 0;\n        d = c;\n        c = b;\n        b = a;\n        a = t1 + t2 | 0;\n      }\n      h0 = h0 + a | 0;\n      h1 = h1 + b | 0;\n      h2 = h2 + c | 0;\n      h3 = h3 + d | 0;\n      h4 = h4 + e | 0;\n      h5 = h5 + f | 0;\n      h6 = h6 + g | 0;\n      h7 = h7 + h | 0;\n    }\n    return new Uint8Array([h0 >> 24 & 0xFF, h0 >> 16 & 0xFF, h0 >> 8 & 0xFF, h0 & 0xFF, h1 >> 24 & 0xFF, h1 >> 16 & 0xFF, h1 >> 8 & 0xFF, h1 & 0xFF, h2 >> 24 & 0xFF, h2 >> 16 & 0xFF, h2 >> 8 & 0xFF, h2 & 0xFF, h3 >> 24 & 0xFF, h3 >> 16 & 0xFF, h3 >> 8 & 0xFF, h3 & 0xFF, h4 >> 24 & 0xFF, h4 >> 16 & 0xFF, h4 >> 8 & 0xFF, h4 & 0xFF, h5 >> 24 & 0xFF, h5 >> 16 & 0xFF, h5 >> 8 & 0xFF, h5 & 0xFF, h6 >> 24 & 0xFF, h6 >> 16 & 0xFF, h6 >> 8 & 0xFF, h6 & 0xFF, h7 >> 24 & 0xFF, h7 >> 16 & 0xFF, h7 >> 8 & 0xFF, h7 & 0xFF]);\n  }\n  return hash;\n}();\nconst calculateSHA512 = function calculateSHA512Closure() {\n  function ch(result, x, y, z, tmp) {\n    result.assign(x);\n    result.and(y);\n    tmp.assign(x);\n    tmp.not();\n    tmp.and(z);\n    result.xor(tmp);\n  }\n  function maj(result, x, y, z, tmp) {\n    result.assign(x);\n    result.and(y);\n    tmp.assign(x);\n    tmp.and(z);\n    result.xor(tmp);\n    tmp.assign(y);\n    tmp.and(z);\n    result.xor(tmp);\n  }\n  function sigma(result, x, tmp) {\n    result.assign(x);\n    result.rotateRight(28);\n    tmp.assign(x);\n    tmp.rotateRight(34);\n    result.xor(tmp);\n    tmp.assign(x);\n    tmp.rotateRight(39);\n    result.xor(tmp);\n  }\n  function sigmaPrime(result, x, tmp) {\n    result.assign(x);\n    result.rotateRight(14);\n    tmp.assign(x);\n    tmp.rotateRight(18);\n    result.xor(tmp);\n    tmp.assign(x);\n    tmp.rotateRight(41);\n    result.xor(tmp);\n  }\n  function littleSigma(result, x, tmp) {\n    result.assign(x);\n    result.rotateRight(1);\n    tmp.assign(x);\n    tmp.rotateRight(8);\n    result.xor(tmp);\n    tmp.assign(x);\n    tmp.shiftRight(7);\n    result.xor(tmp);\n  }\n  function littleSigmaPrime(result, x, tmp) {\n    result.assign(x);\n    result.rotateRight(19);\n    tmp.assign(x);\n    tmp.rotateRight(61);\n    result.xor(tmp);\n    tmp.assign(x);\n    tmp.shiftRight(6);\n    result.xor(tmp);\n  }\n  const k = [new Word64(0x428a2f98, 0xd728ae22), new Word64(0x71374491, 0x23ef65cd), new Word64(0xb5c0fbcf, 0xec4d3b2f), new Word64(0xe9b5dba5, 0x8189dbbc), new Word64(0x3956c25b, 0xf348b538), new Word64(0x59f111f1, 0xb605d019), new Word64(0x923f82a4, 0xaf194f9b), new Word64(0xab1c5ed5, 0xda6d8118), new Word64(0xd807aa98, 0xa3030242), new Word64(0x12835b01, 0x45706fbe), new Word64(0x243185be, 0x4ee4b28c), new Word64(0x550c7dc3, 0xd5ffb4e2), new Word64(0x72be5d74, 0xf27b896f), new Word64(0x80deb1fe, 0x3b1696b1), new Word64(0x9bdc06a7, 0x25c71235), new Word64(0xc19bf174, 0xcf692694), new Word64(0xe49b69c1, 0x9ef14ad2), new Word64(0xefbe4786, 0x384f25e3), new Word64(0x0fc19dc6, 0x8b8cd5b5), new Word64(0x240ca1cc, 0x77ac9c65), new Word64(0x2de92c6f, 0x592b0275), new Word64(0x4a7484aa, 0x6ea6e483), new Word64(0x5cb0a9dc, 0xbd41fbd4), new Word64(0x76f988da, 0x831153b5), new Word64(0x983e5152, 0xee66dfab), new Word64(0xa831c66d, 0x2db43210), new Word64(0xb00327c8, 0x98fb213f), new Word64(0xbf597fc7, 0xbeef0ee4), new Word64(0xc6e00bf3, 0x3da88fc2), new Word64(0xd5a79147, 0x930aa725), new Word64(0x06ca6351, 0xe003826f), new Word64(0x14292967, 0x0a0e6e70), new Word64(0x27b70a85, 0x46d22ffc), new Word64(0x2e1b2138, 0x5c26c926), new Word64(0x4d2c6dfc, 0x5ac42aed), new Word64(0x53380d13, 0x9d95b3df), new Word64(0x650a7354, 0x8baf63de), new Word64(0x766a0abb, 0x3c77b2a8), new Word64(0x81c2c92e, 0x47edaee6), new Word64(0x92722c85, 0x1482353b), new Word64(0xa2bfe8a1, 0x4cf10364), new Word64(0xa81a664b, 0xbc423001), new Word64(0xc24b8b70, 0xd0f89791), new Word64(0xc76c51a3, 0x0654be30), new Word64(0xd192e819, 0xd6ef5218), new Word64(0xd6990624, 0x5565a910), new Word64(0xf40e3585, 0x5771202a), new Word64(0x106aa070, 0x32bbd1b8), new Word64(0x19a4c116, 0xb8d2d0c8), new Word64(0x1e376c08, 0x5141ab53), new Word64(0x2748774c, 0xdf8eeb99), new Word64(0x34b0bcb5, 0xe19b48a8), new Word64(0x391c0cb3, 0xc5c95a63), new Word64(0x4ed8aa4a, 0xe3418acb), new Word64(0x5b9cca4f, 0x7763e373), new Word64(0x682e6ff3, 0xd6b2b8a3), new Word64(0x748f82ee, 0x5defb2fc), new Word64(0x78a5636f, 0x43172f60), new Word64(0x84c87814, 0xa1f0ab72), new Word64(0x8cc70208, 0x1a6439ec), new Word64(0x90befffa, 0x23631e28), new Word64(0xa4506ceb, 0xde82bde9), new Word64(0xbef9a3f7, 0xb2c67915), new Word64(0xc67178f2, 0xe372532b), new Word64(0xca273ece, 0xea26619c), new Word64(0xd186b8c7, 0x21c0c207), new Word64(0xeada7dd6, 0xcde0eb1e), new Word64(0xf57d4f7f, 0xee6ed178), new Word64(0x06f067aa, 0x72176fba), new Word64(0x0a637dc5, 0xa2c898a6), new Word64(0x113f9804, 0xbef90dae), new Word64(0x1b710b35, 0x131c471b), new Word64(0x28db77f5, 0x23047d84), new Word64(0x32caab7b, 0x40c72493), new Word64(0x3c9ebe0a, 0x15c9bebc), new Word64(0x431d67c4, 0x9c100d4c), new Word64(0x4cc5d4be, 0xcb3e42b6), new Word64(0x597f299c, 0xfc657e2a), new Word64(0x5fcb6fab, 0x3ad6faec), new Word64(0x6c44198c, 0x4a475817)];\n  function hash(data, offset, length, mode384 = false) {\n    let h0, h1, h2, h3, h4, h5, h6, h7;\n    if (!mode384) {\n      h0 = new Word64(0x6a09e667, 0xf3bcc908);\n      h1 = new Word64(0xbb67ae85, 0x84caa73b);\n      h2 = new Word64(0x3c6ef372, 0xfe94f82b);\n      h3 = new Word64(0xa54ff53a, 0x5f1d36f1);\n      h4 = new Word64(0x510e527f, 0xade682d1);\n      h5 = new Word64(0x9b05688c, 0x2b3e6c1f);\n      h6 = new Word64(0x1f83d9ab, 0xfb41bd6b);\n      h7 = new Word64(0x5be0cd19, 0x137e2179);\n    } else {\n      h0 = new Word64(0xcbbb9d5d, 0xc1059ed8);\n      h1 = new Word64(0x629a292a, 0x367cd507);\n      h2 = new Word64(0x9159015a, 0x3070dd17);\n      h3 = new Word64(0x152fecd8, 0xf70e5939);\n      h4 = new Word64(0x67332667, 0xffc00b31);\n      h5 = new Word64(0x8eb44a87, 0x68581511);\n      h6 = new Word64(0xdb0c2e0d, 0x64f98fa7);\n      h7 = new Word64(0x47b5481d, 0xbefa4fa4);\n    }\n    const paddedLength = Math.ceil((length + 17) / 128) * 128;\n    const padded = new Uint8Array(paddedLength);\n    let i, j;\n    for (i = 0; i < length; ++i) {\n      padded[i] = data[offset++];\n    }\n    padded[i++] = 0x80;\n    const n = paddedLength - 16;\n    while (i < n) {\n      padded[i++] = 0;\n    }\n    padded[i++] = 0;\n    padded[i++] = 0;\n    padded[i++] = 0;\n    padded[i++] = 0;\n    padded[i++] = 0;\n    padded[i++] = 0;\n    padded[i++] = 0;\n    padded[i++] = 0;\n    padded[i++] = 0;\n    padded[i++] = 0;\n    padded[i++] = 0;\n    padded[i++] = length >>> 29 & 0xff;\n    padded[i++] = length >> 21 & 0xff;\n    padded[i++] = length >> 13 & 0xff;\n    padded[i++] = length >> 5 & 0xff;\n    padded[i++] = length << 3 & 0xff;\n    const w = new Array(80);\n    for (i = 0; i < 80; i++) {\n      w[i] = new Word64(0, 0);\n    }\n    let a = new Word64(0, 0),\n      b = new Word64(0, 0),\n      c = new Word64(0, 0);\n    let d = new Word64(0, 0),\n      e = new Word64(0, 0),\n      f = new Word64(0, 0);\n    let g = new Word64(0, 0),\n      h = new Word64(0, 0);\n    const t1 = new Word64(0, 0),\n      t2 = new Word64(0, 0);\n    const tmp1 = new Word64(0, 0),\n      tmp2 = new Word64(0, 0);\n    let tmp3;\n    for (i = 0; i < paddedLength;) {\n      for (j = 0; j < 16; ++j) {\n        w[j].high = padded[i] << 24 | padded[i + 1] << 16 | padded[i + 2] << 8 | padded[i + 3];\n        w[j].low = padded[i + 4] << 24 | padded[i + 5] << 16 | padded[i + 6] << 8 | padded[i + 7];\n        i += 8;\n      }\n      for (j = 16; j < 80; ++j) {\n        tmp3 = w[j];\n        littleSigmaPrime(tmp3, w[j - 2], tmp2);\n        tmp3.add(w[j - 7]);\n        littleSigma(tmp1, w[j - 15], tmp2);\n        tmp3.add(tmp1);\n        tmp3.add(w[j - 16]);\n      }\n      a.assign(h0);\n      b.assign(h1);\n      c.assign(h2);\n      d.assign(h3);\n      e.assign(h4);\n      f.assign(h5);\n      g.assign(h6);\n      h.assign(h7);\n      for (j = 0; j < 80; ++j) {\n        t1.assign(h);\n        sigmaPrime(tmp1, e, tmp2);\n        t1.add(tmp1);\n        ch(tmp1, e, f, g, tmp2);\n        t1.add(tmp1);\n        t1.add(k[j]);\n        t1.add(w[j]);\n        sigma(t2, a, tmp2);\n        maj(tmp1, a, b, c, tmp2);\n        t2.add(tmp1);\n        tmp3 = h;\n        h = g;\n        g = f;\n        f = e;\n        d.add(t1);\n        e = d;\n        d = c;\n        c = b;\n        b = a;\n        tmp3.assign(t1);\n        tmp3.add(t2);\n        a = tmp3;\n      }\n      h0.add(a);\n      h1.add(b);\n      h2.add(c);\n      h3.add(d);\n      h4.add(e);\n      h5.add(f);\n      h6.add(g);\n      h7.add(h);\n    }\n    let result;\n    if (!mode384) {\n      result = new Uint8Array(64);\n      h0.copyTo(result, 0);\n      h1.copyTo(result, 8);\n      h2.copyTo(result, 16);\n      h3.copyTo(result, 24);\n      h4.copyTo(result, 32);\n      h5.copyTo(result, 40);\n      h6.copyTo(result, 48);\n      h7.copyTo(result, 56);\n    } else {\n      result = new Uint8Array(48);\n      h0.copyTo(result, 0);\n      h1.copyTo(result, 8);\n      h2.copyTo(result, 16);\n      h3.copyTo(result, 24);\n      h4.copyTo(result, 32);\n      h5.copyTo(result, 40);\n    }\n    return result;\n  }\n  return hash;\n}();\nfunction calculateSHA384(data, offset, length) {\n  return calculateSHA512(data, offset, length, true);\n}\nclass NullCipher {\n  decryptBlock(data) {\n    return data;\n  }\n  encrypt(data) {\n    return data;\n  }\n}\nclass AESBaseCipher {\n  constructor() {\n    if (this.constructor === AESBaseCipher) {\n      unreachable(\"Cannot initialize AESBaseCipher.\");\n    }\n    this._s = new Uint8Array([0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16]);\n    this._inv_s = new Uint8Array([0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d]);\n    this._mix = new Uint32Array([0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927, 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45, 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb, 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381, 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf, 0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66, 0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a, 0xab73d323, 0xa57ade28, 0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012, 0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec, 0x1f9d45f1, 0x119448fa, 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e, 0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2, 0xad766df6, 0xa37f60fd, 0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7, 0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89, 0xf9082b94, 0xf701269f, 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b, 0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77, 0x3daed51e, 0x33a7d815, 0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f, 0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa, 0x527bf8b7, 0x5c72f5bc, 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8, 0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4, 0x96dd063d, 0x98d40b36, 0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c, 0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742, 0xc2a3405f, 0xccaa4d54, 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea, 0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6, 0x31a4b2af, 0x3fadbfa4, 0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e, 0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360, 0x854a247d, 0x8b432976, 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502, 0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e, 0x9ad7618c, 0x94de6c87, 0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd, 0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3, 0xcea927ee, 0xc0a02ae5, 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621, 0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d, 0x0a0fd964, 0x0406d46f, 0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55, 0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26, 0xc8ac993b, 0xc6a59430, 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844, 0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68, 0x0c0a67b1, 0x02036aba, 0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480, 0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce, 0x587421d3, 0x567d2cd8, 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67, 0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b, 0x47e96422, 0x49e06929, 0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713, 0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed, 0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f, 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3]);\n    this._mixCol = new Uint8Array(256);\n    for (let i = 0; i < 256; i++) {\n      this._mixCol[i] = i < 128 ? i << 1 : i << 1 ^ 0x1b;\n    }\n    this.buffer = new Uint8Array(16);\n    this.bufferPosition = 0;\n  }\n  _expandKey(cipherKey) {\n    unreachable(\"Cannot call `_expandKey` on the base class\");\n  }\n  _decrypt(input, key) {\n    let t, u, v;\n    const state = new Uint8Array(16);\n    state.set(input);\n    for (let j = 0, k = this._keySize; j < 16; ++j, ++k) {\n      state[j] ^= key[k];\n    }\n    for (let i = this._cyclesOfRepetition - 1; i >= 1; --i) {\n      t = state[13];\n      state[13] = state[9];\n      state[9] = state[5];\n      state[5] = state[1];\n      state[1] = t;\n      t = state[14];\n      u = state[10];\n      state[14] = state[6];\n      state[10] = state[2];\n      state[6] = t;\n      state[2] = u;\n      t = state[15];\n      u = state[11];\n      v = state[7];\n      state[15] = state[3];\n      state[11] = t;\n      state[7] = u;\n      state[3] = v;\n      for (let j = 0; j < 16; ++j) {\n        state[j] = this._inv_s[state[j]];\n      }\n      for (let j = 0, k = i * 16; j < 16; ++j, ++k) {\n        state[j] ^= key[k];\n      }\n      for (let j = 0; j < 16; j += 4) {\n        const s0 = this._mix[state[j]];\n        const s1 = this._mix[state[j + 1]];\n        const s2 = this._mix[state[j + 2]];\n        const s3 = this._mix[state[j + 3]];\n        t = s0 ^ s1 >>> 8 ^ s1 << 24 ^ s2 >>> 16 ^ s2 << 16 ^ s3 >>> 24 ^ s3 << 8;\n        state[j] = t >>> 24 & 0xff;\n        state[j + 1] = t >> 16 & 0xff;\n        state[j + 2] = t >> 8 & 0xff;\n        state[j + 3] = t & 0xff;\n      }\n    }\n    t = state[13];\n    state[13] = state[9];\n    state[9] = state[5];\n    state[5] = state[1];\n    state[1] = t;\n    t = state[14];\n    u = state[10];\n    state[14] = state[6];\n    state[10] = state[2];\n    state[6] = t;\n    state[2] = u;\n    t = state[15];\n    u = state[11];\n    v = state[7];\n    state[15] = state[3];\n    state[11] = t;\n    state[7] = u;\n    state[3] = v;\n    for (let j = 0; j < 16; ++j) {\n      state[j] = this._inv_s[state[j]];\n      state[j] ^= key[j];\n    }\n    return state;\n  }\n  _encrypt(input, key) {\n    const s = this._s;\n    let t, u, v;\n    const state = new Uint8Array(16);\n    state.set(input);\n    for (let j = 0; j < 16; ++j) {\n      state[j] ^= key[j];\n    }\n    for (let i = 1; i < this._cyclesOfRepetition; i++) {\n      for (let j = 0; j < 16; ++j) {\n        state[j] = s[state[j]];\n      }\n      v = state[1];\n      state[1] = state[5];\n      state[5] = state[9];\n      state[9] = state[13];\n      state[13] = v;\n      v = state[2];\n      u = state[6];\n      state[2] = state[10];\n      state[6] = state[14];\n      state[10] = v;\n      state[14] = u;\n      v = state[3];\n      u = state[7];\n      t = state[11];\n      state[3] = state[15];\n      state[7] = v;\n      state[11] = u;\n      state[15] = t;\n      for (let j = 0; j < 16; j += 4) {\n        const s0 = state[j + 0];\n        const s1 = state[j + 1];\n        const s2 = state[j + 2];\n        const s3 = state[j + 3];\n        t = s0 ^ s1 ^ s2 ^ s3;\n        state[j + 0] ^= t ^ this._mixCol[s0 ^ s1];\n        state[j + 1] ^= t ^ this._mixCol[s1 ^ s2];\n        state[j + 2] ^= t ^ this._mixCol[s2 ^ s3];\n        state[j + 3] ^= t ^ this._mixCol[s3 ^ s0];\n      }\n      for (let j = 0, k = i * 16; j < 16; ++j, ++k) {\n        state[j] ^= key[k];\n      }\n    }\n    for (let j = 0; j < 16; ++j) {\n      state[j] = s[state[j]];\n    }\n    v = state[1];\n    state[1] = state[5];\n    state[5] = state[9];\n    state[9] = state[13];\n    state[13] = v;\n    v = state[2];\n    u = state[6];\n    state[2] = state[10];\n    state[6] = state[14];\n    state[10] = v;\n    state[14] = u;\n    v = state[3];\n    u = state[7];\n    t = state[11];\n    state[3] = state[15];\n    state[7] = v;\n    state[11] = u;\n    state[15] = t;\n    for (let j = 0, k = this._keySize; j < 16; ++j, ++k) {\n      state[j] ^= key[k];\n    }\n    return state;\n  }\n  _decryptBlock2(data, finalize) {\n    const sourceLength = data.length;\n    let buffer = this.buffer,\n      bufferLength = this.bufferPosition;\n    const result = [];\n    let iv = this.iv;\n    for (let i = 0; i < sourceLength; ++i) {\n      buffer[bufferLength] = data[i];\n      ++bufferLength;\n      if (bufferLength < 16) {\n        continue;\n      }\n      const plain = this._decrypt(buffer, this._key);\n      for (let j = 0; j < 16; ++j) {\n        plain[j] ^= iv[j];\n      }\n      iv = buffer;\n      result.push(plain);\n      buffer = new Uint8Array(16);\n      bufferLength = 0;\n    }\n    this.buffer = buffer;\n    this.bufferLength = bufferLength;\n    this.iv = iv;\n    if (result.length === 0) {\n      return new Uint8Array(0);\n    }\n    let outputLength = 16 * result.length;\n    if (finalize) {\n      const lastBlock = result.at(-1);\n      let psLen = lastBlock[15];\n      if (psLen <= 16) {\n        for (let i = 15, ii = 16 - psLen; i >= ii; --i) {\n          if (lastBlock[i] !== psLen) {\n            psLen = 0;\n            break;\n          }\n        }\n        outputLength -= psLen;\n        result[result.length - 1] = lastBlock.subarray(0, 16 - psLen);\n      }\n    }\n    const output = new Uint8Array(outputLength);\n    for (let i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) {\n      output.set(result[i], j);\n    }\n    return output;\n  }\n  decryptBlock(data, finalize, iv = null) {\n    const sourceLength = data.length;\n    const buffer = this.buffer;\n    let bufferLength = this.bufferPosition;\n    if (iv) {\n      this.iv = iv;\n    } else {\n      for (let i = 0; bufferLength < 16 && i < sourceLength; ++i, ++bufferLength) {\n        buffer[bufferLength] = data[i];\n      }\n      if (bufferLength < 16) {\n        this.bufferLength = bufferLength;\n        return new Uint8Array(0);\n      }\n      this.iv = buffer;\n      data = data.subarray(16);\n    }\n    this.buffer = new Uint8Array(16);\n    this.bufferLength = 0;\n    this.decryptBlock = this._decryptBlock2;\n    return this.decryptBlock(data, finalize);\n  }\n  encrypt(data, iv) {\n    const sourceLength = data.length;\n    let buffer = this.buffer,\n      bufferLength = this.bufferPosition;\n    const result = [];\n    if (!iv) {\n      iv = new Uint8Array(16);\n    }\n    for (let i = 0; i < sourceLength; ++i) {\n      buffer[bufferLength] = data[i];\n      ++bufferLength;\n      if (bufferLength < 16) {\n        continue;\n      }\n      for (let j = 0; j < 16; ++j) {\n        buffer[j] ^= iv[j];\n      }\n      const cipher = this._encrypt(buffer, this._key);\n      iv = cipher;\n      result.push(cipher);\n      buffer = new Uint8Array(16);\n      bufferLength = 0;\n    }\n    this.buffer = buffer;\n    this.bufferLength = bufferLength;\n    this.iv = iv;\n    if (result.length === 0) {\n      return new Uint8Array(0);\n    }\n    const outputLength = 16 * result.length;\n    const output = new Uint8Array(outputLength);\n    for (let i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) {\n      output.set(result[i], j);\n    }\n    return output;\n  }\n}\nclass AES128Cipher extends AESBaseCipher {\n  constructor(key) {\n    super();\n    this._cyclesOfRepetition = 10;\n    this._keySize = 160;\n    this._rcon = new Uint8Array([0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d]);\n    this._key = this._expandKey(key);\n  }\n  _expandKey(cipherKey) {\n    const b = 176;\n    const s = this._s;\n    const rcon = this._rcon;\n    const result = new Uint8Array(b);\n    result.set(cipherKey);\n    for (let j = 16, i = 1; j < b; ++i) {\n      let t1 = result[j - 3];\n      let t2 = result[j - 2];\n      let t3 = result[j - 1];\n      let t4 = result[j - 4];\n      t1 = s[t1];\n      t2 = s[t2];\n      t3 = s[t3];\n      t4 = s[t4];\n      t1 ^= rcon[i];\n      for (let n = 0; n < 4; ++n) {\n        result[j] = t1 ^= result[j - 16];\n        j++;\n        result[j] = t2 ^= result[j - 16];\n        j++;\n        result[j] = t3 ^= result[j - 16];\n        j++;\n        result[j] = t4 ^= result[j - 16];\n        j++;\n      }\n    }\n    return result;\n  }\n}\nclass AES256Cipher extends AESBaseCipher {\n  constructor(key) {\n    super();\n    this._cyclesOfRepetition = 14;\n    this._keySize = 224;\n    this._key = this._expandKey(key);\n  }\n  _expandKey(cipherKey) {\n    const b = 240;\n    const s = this._s;\n    const result = new Uint8Array(b);\n    result.set(cipherKey);\n    let r = 1;\n    let t1, t2, t3, t4;\n    for (let j = 32, i = 1; j < b; ++i) {\n      if (j % 32 === 16) {\n        t1 = s[t1];\n        t2 = s[t2];\n        t3 = s[t3];\n        t4 = s[t4];\n      } else if (j % 32 === 0) {\n        t1 = result[j - 3];\n        t2 = result[j - 2];\n        t3 = result[j - 1];\n        t4 = result[j - 4];\n        t1 = s[t1];\n        t2 = s[t2];\n        t3 = s[t3];\n        t4 = s[t4];\n        t1 ^= r;\n        if ((r <<= 1) >= 256) {\n          r = (r ^ 0x1b) & 0xff;\n        }\n      }\n      for (let n = 0; n < 4; ++n) {\n        result[j] = t1 ^= result[j - 32];\n        j++;\n        result[j] = t2 ^= result[j - 32];\n        j++;\n        result[j] = t3 ^= result[j - 32];\n        j++;\n        result[j] = t4 ^= result[j - 32];\n        j++;\n      }\n    }\n    return result;\n  }\n}\nclass PDF17 {\n  checkOwnerPassword(password, ownerValidationSalt, userBytes, ownerPassword) {\n    const hashData = new Uint8Array(password.length + 56);\n    hashData.set(password, 0);\n    hashData.set(ownerValidationSalt, password.length);\n    hashData.set(userBytes, password.length + ownerValidationSalt.length);\n    const result = calculateSHA256(hashData, 0, hashData.length);\n    return isArrayEqual(result, ownerPassword);\n  }\n  checkUserPassword(password, userValidationSalt, userPassword) {\n    const hashData = new Uint8Array(password.length + 8);\n    hashData.set(password, 0);\n    hashData.set(userValidationSalt, password.length);\n    const result = calculateSHA256(hashData, 0, hashData.length);\n    return isArrayEqual(result, userPassword);\n  }\n  getOwnerKey(password, ownerKeySalt, userBytes, ownerEncryption) {\n    const hashData = new Uint8Array(password.length + 56);\n    hashData.set(password, 0);\n    hashData.set(ownerKeySalt, password.length);\n    hashData.set(userBytes, password.length + ownerKeySalt.length);\n    const key = calculateSHA256(hashData, 0, hashData.length);\n    const cipher = new AES256Cipher(key);\n    return cipher.decryptBlock(ownerEncryption, false, new Uint8Array(16));\n  }\n  getUserKey(password, userKeySalt, userEncryption) {\n    const hashData = new Uint8Array(password.length + 8);\n    hashData.set(password, 0);\n    hashData.set(userKeySalt, password.length);\n    const key = calculateSHA256(hashData, 0, hashData.length);\n    const cipher = new AES256Cipher(key);\n    return cipher.decryptBlock(userEncryption, false, new Uint8Array(16));\n  }\n}\nclass PDF20 {\n  _hash(password, input, userBytes) {\n    let k = calculateSHA256(input, 0, input.length).subarray(0, 32);\n    let e = [0];\n    let i = 0;\n    while (i < 64 || e.at(-1) > i - 32) {\n      const combinedLength = password.length + k.length + userBytes.length,\n        combinedArray = new Uint8Array(combinedLength);\n      let writeOffset = 0;\n      combinedArray.set(password, writeOffset);\n      writeOffset += password.length;\n      combinedArray.set(k, writeOffset);\n      writeOffset += k.length;\n      combinedArray.set(userBytes, writeOffset);\n      const k1 = new Uint8Array(combinedLength * 64);\n      for (let j = 0, pos = 0; j < 64; j++, pos += combinedLength) {\n        k1.set(combinedArray, pos);\n      }\n      const cipher = new AES128Cipher(k.subarray(0, 16));\n      e = cipher.encrypt(k1, k.subarray(16, 32));\n      const remainder = e.slice(0, 16).reduce((a, b) => a + b, 0) % 3;\n      if (remainder === 0) {\n        k = calculateSHA256(e, 0, e.length);\n      } else if (remainder === 1) {\n        k = calculateSHA384(e, 0, e.length);\n      } else if (remainder === 2) {\n        k = calculateSHA512(e, 0, e.length);\n      }\n      i++;\n    }\n    return k.subarray(0, 32);\n  }\n  checkOwnerPassword(password, ownerValidationSalt, userBytes, ownerPassword) {\n    const hashData = new Uint8Array(password.length + 56);\n    hashData.set(password, 0);\n    hashData.set(ownerValidationSalt, password.length);\n    hashData.set(userBytes, password.length + ownerValidationSalt.length);\n    const result = this._hash(password, hashData, userBytes);\n    return isArrayEqual(result, ownerPassword);\n  }\n  checkUserPassword(password, userValidationSalt, userPassword) {\n    const hashData = new Uint8Array(password.length + 8);\n    hashData.set(password, 0);\n    hashData.set(userValidationSalt, password.length);\n    const result = this._hash(password, hashData, []);\n    return isArrayEqual(result, userPassword);\n  }\n  getOwnerKey(password, ownerKeySalt, userBytes, ownerEncryption) {\n    const hashData = new Uint8Array(password.length + 56);\n    hashData.set(password, 0);\n    hashData.set(ownerKeySalt, password.length);\n    hashData.set(userBytes, password.length + ownerKeySalt.length);\n    const key = this._hash(password, hashData, userBytes);\n    const cipher = new AES256Cipher(key);\n    return cipher.decryptBlock(ownerEncryption, false, new Uint8Array(16));\n  }\n  getUserKey(password, userKeySalt, userEncryption) {\n    const hashData = new Uint8Array(password.length + 8);\n    hashData.set(password, 0);\n    hashData.set(userKeySalt, password.length);\n    const key = this._hash(password, hashData, []);\n    const cipher = new AES256Cipher(key);\n    return cipher.decryptBlock(userEncryption, false, new Uint8Array(16));\n  }\n}\nclass CipherTransform {\n  constructor(stringCipherConstructor, streamCipherConstructor) {\n    this.StringCipherConstructor = stringCipherConstructor;\n    this.StreamCipherConstructor = streamCipherConstructor;\n  }\n  createStream(stream, length) {\n    const cipher = new this.StreamCipherConstructor();\n    return new DecryptStream(stream, length, function cipherTransformDecryptStream(data, finalize) {\n      return cipher.decryptBlock(data, finalize);\n    });\n  }\n  decryptString(s) {\n    const cipher = new this.StringCipherConstructor();\n    let data = stringToBytes(s);\n    data = cipher.decryptBlock(data, true);\n    return bytesToString(data);\n  }\n  encryptString(s) {\n    const cipher = new this.StringCipherConstructor();\n    if (cipher instanceof AESBaseCipher) {\n      const strLen = s.length;\n      const pad = 16 - strLen % 16;\n      s += String.fromCharCode(pad).repeat(pad);\n      const iv = new Uint8Array(16);\n      if (typeof crypto !== \"undefined\") {\n        crypto.getRandomValues(iv);\n      } else {\n        for (let i = 0; i < 16; i++) {\n          iv[i] = Math.floor(256 * Math.random());\n        }\n      }\n      let data = stringToBytes(s);\n      data = cipher.encrypt(data, iv);\n      const buf = new Uint8Array(16 + data.length);\n      buf.set(iv);\n      buf.set(data, 16);\n      return bytesToString(buf);\n    }\n    let data = stringToBytes(s);\n    data = cipher.encrypt(data);\n    return bytesToString(data);\n  }\n}\nclass CipherTransformFactory {\n  static #defaultPasswordBytes = new Uint8Array([0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08, 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80, 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a]);\n  #createEncryptionKey20(revision, password, ownerPassword, ownerValidationSalt, ownerKeySalt, uBytes, userPassword, userValidationSalt, userKeySalt, ownerEncryption, userEncryption, perms) {\n    if (password) {\n      const passwordLength = Math.min(127, password.length);\n      password = password.subarray(0, passwordLength);\n    } else {\n      password = [];\n    }\n    const pdfAlgorithm = revision === 6 ? new PDF20() : new PDF17();\n    if (pdfAlgorithm.checkUserPassword(password, userValidationSalt, userPassword)) {\n      return pdfAlgorithm.getUserKey(password, userKeySalt, userEncryption);\n    } else if (password.length && pdfAlgorithm.checkOwnerPassword(password, ownerValidationSalt, uBytes, ownerPassword)) {\n      return pdfAlgorithm.getOwnerKey(password, ownerKeySalt, uBytes, ownerEncryption);\n    }\n    return null;\n  }\n  #prepareKeyData(fileId, password, ownerPassword, userPassword, flags, revision, keyLength, encryptMetadata) {\n    const hashDataSize = 40 + ownerPassword.length + fileId.length;\n    const hashData = new Uint8Array(hashDataSize);\n    let i = 0,\n      j,\n      n;\n    if (password) {\n      n = Math.min(32, password.length);\n      for (; i < n; ++i) {\n        hashData[i] = password[i];\n      }\n    }\n    j = 0;\n    while (i < 32) {\n      hashData[i++] = CipherTransformFactory.#defaultPasswordBytes[j++];\n    }\n    for (j = 0, n = ownerPassword.length; j < n; ++j) {\n      hashData[i++] = ownerPassword[j];\n    }\n    hashData[i++] = flags & 0xff;\n    hashData[i++] = flags >> 8 & 0xff;\n    hashData[i++] = flags >> 16 & 0xff;\n    hashData[i++] = flags >>> 24 & 0xff;\n    for (j = 0, n = fileId.length; j < n; ++j) {\n      hashData[i++] = fileId[j];\n    }\n    if (revision >= 4 && !encryptMetadata) {\n      hashData[i++] = 0xff;\n      hashData[i++] = 0xff;\n      hashData[i++] = 0xff;\n      hashData[i++] = 0xff;\n    }\n    let hash = calculateMD5(hashData, 0, i);\n    const keyLengthInBytes = keyLength >> 3;\n    if (revision >= 3) {\n      for (j = 0; j < 50; ++j) {\n        hash = calculateMD5(hash, 0, keyLengthInBytes);\n      }\n    }\n    const encryptionKey = hash.subarray(0, keyLengthInBytes);\n    let cipher, checkData;\n    if (revision >= 3) {\n      for (i = 0; i < 32; ++i) {\n        hashData[i] = CipherTransformFactory.#defaultPasswordBytes[i];\n      }\n      for (j = 0, n = fileId.length; j < n; ++j) {\n        hashData[i++] = fileId[j];\n      }\n      cipher = new ARCFourCipher(encryptionKey);\n      checkData = cipher.encryptBlock(calculateMD5(hashData, 0, i));\n      n = encryptionKey.length;\n      const derivedKey = new Uint8Array(n);\n      for (j = 1; j <= 19; ++j) {\n        for (let k = 0; k < n; ++k) {\n          derivedKey[k] = encryptionKey[k] ^ j;\n        }\n        cipher = new ARCFourCipher(derivedKey);\n        checkData = cipher.encryptBlock(checkData);\n      }\n      for (j = 0, n = checkData.length; j < n; ++j) {\n        if (userPassword[j] !== checkData[j]) {\n          return null;\n        }\n      }\n    } else {\n      cipher = new ARCFourCipher(encryptionKey);\n      checkData = cipher.encryptBlock(CipherTransformFactory.#defaultPasswordBytes);\n      for (j = 0, n = checkData.length; j < n; ++j) {\n        if (userPassword[j] !== checkData[j]) {\n          return null;\n        }\n      }\n    }\n    return encryptionKey;\n  }\n  #decodeUserPassword(password, ownerPassword, revision, keyLength) {\n    const hashData = new Uint8Array(32);\n    let i = 0;\n    const n = Math.min(32, password.length);\n    for (; i < n; ++i) {\n      hashData[i] = password[i];\n    }\n    let j = 0;\n    while (i < 32) {\n      hashData[i++] = CipherTransformFactory.#defaultPasswordBytes[j++];\n    }\n    let hash = calculateMD5(hashData, 0, i);\n    const keyLengthInBytes = keyLength >> 3;\n    if (revision >= 3) {\n      for (j = 0; j < 50; ++j) {\n        hash = calculateMD5(hash, 0, hash.length);\n      }\n    }\n    let cipher, userPassword;\n    if (revision >= 3) {\n      userPassword = ownerPassword;\n      const derivedKey = new Uint8Array(keyLengthInBytes);\n      for (j = 19; j >= 0; j--) {\n        for (let k = 0; k < keyLengthInBytes; ++k) {\n          derivedKey[k] = hash[k] ^ j;\n        }\n        cipher = new ARCFourCipher(derivedKey);\n        userPassword = cipher.encryptBlock(userPassword);\n      }\n    } else {\n      cipher = new ARCFourCipher(hash.subarray(0, keyLengthInBytes));\n      userPassword = cipher.encryptBlock(ownerPassword);\n    }\n    return userPassword;\n  }\n  #buildObjectKey(num, gen, encryptionKey, isAes = false) {\n    const key = new Uint8Array(encryptionKey.length + 9);\n    const n = encryptionKey.length;\n    let i;\n    for (i = 0; i < n; ++i) {\n      key[i] = encryptionKey[i];\n    }\n    key[i++] = num & 0xff;\n    key[i++] = num >> 8 & 0xff;\n    key[i++] = num >> 16 & 0xff;\n    key[i++] = gen & 0xff;\n    key[i++] = gen >> 8 & 0xff;\n    if (isAes) {\n      key[i++] = 0x73;\n      key[i++] = 0x41;\n      key[i++] = 0x6c;\n      key[i++] = 0x54;\n    }\n    const hash = calculateMD5(key, 0, i);\n    return hash.subarray(0, Math.min(encryptionKey.length + 5, 16));\n  }\n  #buildCipherConstructor(cf, name, num, gen, key) {\n    if (!(name instanceof Name)) {\n      throw new FormatError(\"Invalid crypt filter name.\");\n    }\n    const self = this;\n    const cryptFilter = cf.get(name.name);\n    const cfm = cryptFilter?.get(\"CFM\");\n    if (!cfm || cfm.name === \"None\") {\n      return function () {\n        return new NullCipher();\n      };\n    }\n    if (cfm.name === \"V2\") {\n      return function () {\n        return new ARCFourCipher(self.#buildObjectKey(num, gen, key, false));\n      };\n    }\n    if (cfm.name === \"AESV2\") {\n      return function () {\n        return new AES128Cipher(self.#buildObjectKey(num, gen, key, true));\n      };\n    }\n    if (cfm.name === \"AESV3\") {\n      return function () {\n        return new AES256Cipher(key);\n      };\n    }\n    throw new FormatError(\"Unknown crypto method\");\n  }\n  constructor(dict, fileId, password) {\n    const filter = dict.get(\"Filter\");\n    if (!isName(filter, \"Standard\")) {\n      throw new FormatError(\"unknown encryption method\");\n    }\n    this.filterName = filter.name;\n    this.dict = dict;\n    const algorithm = dict.get(\"V\");\n    if (!Number.isInteger(algorithm) || algorithm !== 1 && algorithm !== 2 && algorithm !== 4 && algorithm !== 5) {\n      throw new FormatError(\"unsupported encryption algorithm\");\n    }\n    this.algorithm = algorithm;\n    let keyLength = dict.get(\"Length\");\n    if (!keyLength) {\n      if (algorithm <= 3) {\n        keyLength = 40;\n      } else {\n        const cfDict = dict.get(\"CF\");\n        const streamCryptoName = dict.get(\"StmF\");\n        if (cfDict instanceof Dict && streamCryptoName instanceof Name) {\n          cfDict.suppressEncryption = true;\n          const handlerDict = cfDict.get(streamCryptoName.name);\n          keyLength = handlerDict?.get(\"Length\") || 128;\n          if (keyLength < 40) {\n            keyLength <<= 3;\n          }\n        }\n      }\n    }\n    if (!Number.isInteger(keyLength) || keyLength < 40 || keyLength % 8 !== 0) {\n      throw new FormatError(\"invalid key length\");\n    }\n    const ownerBytes = stringToBytes(dict.get(\"O\")),\n      userBytes = stringToBytes(dict.get(\"U\"));\n    const ownerPassword = ownerBytes.subarray(0, 32);\n    const userPassword = userBytes.subarray(0, 32);\n    const flags = dict.get(\"P\");\n    const revision = dict.get(\"R\");\n    const encryptMetadata = (algorithm === 4 || algorithm === 5) && dict.get(\"EncryptMetadata\") !== false;\n    this.encryptMetadata = encryptMetadata;\n    const fileIdBytes = stringToBytes(fileId);\n    let passwordBytes;\n    if (password) {\n      if (revision === 6) {\n        try {\n          password = utf8StringToString(password);\n        } catch {\n          warn(\"CipherTransformFactory: Unable to convert UTF8 encoded password.\");\n        }\n      }\n      passwordBytes = stringToBytes(password);\n    }\n    let encryptionKey;\n    if (algorithm !== 5) {\n      encryptionKey = this.#prepareKeyData(fileIdBytes, passwordBytes, ownerPassword, userPassword, flags, revision, keyLength, encryptMetadata);\n    } else {\n      const ownerValidationSalt = ownerBytes.subarray(32, 40);\n      const ownerKeySalt = ownerBytes.subarray(40, 48);\n      const uBytes = userBytes.subarray(0, 48);\n      const userValidationSalt = userBytes.subarray(32, 40);\n      const userKeySalt = userBytes.subarray(40, 48);\n      const ownerEncryption = stringToBytes(dict.get(\"OE\"));\n      const userEncryption = stringToBytes(dict.get(\"UE\"));\n      const perms = stringToBytes(dict.get(\"Perms\"));\n      encryptionKey = this.#createEncryptionKey20(revision, passwordBytes, ownerPassword, ownerValidationSalt, ownerKeySalt, uBytes, userPassword, userValidationSalt, userKeySalt, ownerEncryption, userEncryption, perms);\n    }\n    if (!encryptionKey && !password) {\n      throw new PasswordException(\"No password given\", PasswordResponses.NEED_PASSWORD);\n    } else if (!encryptionKey && password) {\n      const decodedPassword = this.#decodeUserPassword(passwordBytes, ownerPassword, revision, keyLength);\n      encryptionKey = this.#prepareKeyData(fileIdBytes, decodedPassword, ownerPassword, userPassword, flags, revision, keyLength, encryptMetadata);\n    }\n    if (!encryptionKey) {\n      throw new PasswordException(\"Incorrect Password\", PasswordResponses.INCORRECT_PASSWORD);\n    }\n    this.encryptionKey = encryptionKey;\n    if (algorithm >= 4) {\n      const cf = dict.get(\"CF\");\n      if (cf instanceof Dict) {\n        cf.suppressEncryption = true;\n      }\n      this.cf = cf;\n      this.stmf = dict.get(\"StmF\") || Name.get(\"Identity\");\n      this.strf = dict.get(\"StrF\") || Name.get(\"Identity\");\n      this.eff = dict.get(\"EFF\") || this.stmf;\n    }\n  }\n  createCipherTransform(num, gen) {\n    if (this.algorithm === 4 || this.algorithm === 5) {\n      return new CipherTransform(this.#buildCipherConstructor(this.cf, this.strf, num, gen, this.encryptionKey), this.#buildCipherConstructor(this.cf, this.stmf, num, gen, this.encryptionKey));\n    }\n    const key = this.#buildObjectKey(num, gen, this.encryptionKey, false);\n    const cipherConstructor = function () {\n      return new ARCFourCipher(key);\n    };\n    return new CipherTransform(cipherConstructor, cipherConstructor);\n  }\n}\n\n;// ./src/core/writer.js\n\n\n\n\n\n\n\nasync function writeObject(ref, obj, buffer, {\n  encrypt = null\n}) {\n  const transform = encrypt?.createCipherTransform(ref.num, ref.gen);\n  buffer.push(`${ref.num} ${ref.gen} obj\\n`);\n  if (obj instanceof Dict) {\n    await writeDict(obj, buffer, transform);\n  } else if (obj instanceof BaseStream) {\n    await writeStream(obj, buffer, transform);\n  } else if (Array.isArray(obj) || ArrayBuffer.isView(obj)) {\n    await writeArray(obj, buffer, transform);\n  }\n  buffer.push(\"\\nendobj\\n\");\n}\nasync function writeDict(dict, buffer, transform) {\n  buffer.push(\"<<\");\n  for (const key of dict.getKeys()) {\n    buffer.push(` /${escapePDFName(key)} `);\n    await writeValue(dict.getRaw(key), buffer, transform);\n  }\n  buffer.push(\">>\");\n}\nasync function writeStream(stream, buffer, transform) {\n  let bytes = stream.getBytes();\n  const {\n    dict\n  } = stream;\n  const [filter, params] = await Promise.all([dict.getAsync(\"Filter\"), dict.getAsync(\"DecodeParms\")]);\n  const filterZero = Array.isArray(filter) ? await dict.xref.fetchIfRefAsync(filter[0]) : filter;\n  const isFilterZeroFlateDecode = isName(filterZero, \"FlateDecode\");\n  const MIN_LENGTH_FOR_COMPRESSING = 256;\n  if (typeof CompressionStream !== \"undefined\" && (bytes.length >= MIN_LENGTH_FOR_COMPRESSING || isFilterZeroFlateDecode)) {\n    try {\n      const cs = new CompressionStream(\"deflate\");\n      const writer = cs.writable.getWriter();\n      writer.write(bytes);\n      writer.close();\n      const buf = await new Response(cs.readable).arrayBuffer();\n      bytes = new Uint8Array(buf);\n      let newFilter, newParams;\n      if (!filter) {\n        newFilter = Name.get(\"FlateDecode\");\n      } else if (!isFilterZeroFlateDecode) {\n        newFilter = Array.isArray(filter) ? [Name.get(\"FlateDecode\"), ...filter] : [Name.get(\"FlateDecode\"), filter];\n        if (params) {\n          newParams = Array.isArray(params) ? [null, ...params] : [null, params];\n        }\n      }\n      if (newFilter) {\n        dict.set(\"Filter\", newFilter);\n      }\n      if (newParams) {\n        dict.set(\"DecodeParms\", newParams);\n      }\n    } catch (ex) {\n      info(`writeStream - cannot compress data: \"${ex}\".`);\n    }\n  }\n  let string = bytesToString(bytes);\n  if (transform) {\n    string = transform.encryptString(string);\n  }\n  dict.set(\"Length\", string.length);\n  await writeDict(dict, buffer, transform);\n  buffer.push(\" stream\\n\", string, \"\\nendstream\");\n}\nasync function writeArray(array, buffer, transform) {\n  buffer.push(\"[\");\n  let first = true;\n  for (const val of array) {\n    if (!first) {\n      buffer.push(\" \");\n    } else {\n      first = false;\n    }\n    await writeValue(val, buffer, transform);\n  }\n  buffer.push(\"]\");\n}\nasync function writeValue(value, buffer, transform) {\n  if (value instanceof Name) {\n    buffer.push(`/${escapePDFName(value.name)}`);\n  } else if (value instanceof Ref) {\n    buffer.push(`${value.num} ${value.gen} R`);\n  } else if (Array.isArray(value) || ArrayBuffer.isView(value)) {\n    await writeArray(value, buffer, transform);\n  } else if (typeof value === \"string\") {\n    if (transform) {\n      value = transform.encryptString(value);\n    }\n    buffer.push(`(${escapeString(value)})`);\n  } else if (typeof value === \"number\") {\n    buffer.push(numberToString(value));\n  } else if (typeof value === \"boolean\") {\n    buffer.push(value.toString());\n  } else if (value instanceof Dict) {\n    await writeDict(value, buffer, transform);\n  } else if (value instanceof BaseStream) {\n    await writeStream(value, buffer, transform);\n  } else if (value === null) {\n    buffer.push(\"null\");\n  } else {\n    warn(`Unhandled value in writer: ${typeof value}, please file a bug.`);\n  }\n}\nfunction writeInt(number, size, offset, buffer) {\n  for (let i = size + offset - 1; i > offset - 1; i--) {\n    buffer[i] = number & 0xff;\n    number >>= 8;\n  }\n  return offset + size;\n}\nfunction writeString(string, offset, buffer) {\n  for (let i = 0, len = string.length; i < len; i++) {\n    buffer[offset + i] = string.charCodeAt(i) & 0xff;\n  }\n}\nfunction computeMD5(filesize, xrefInfo) {\n  const time = Math.floor(Date.now() / 1000);\n  const filename = xrefInfo.filename || \"\";\n  const md5Buffer = [time.toString(), filename, filesize.toString()];\n  let md5BufferLen = md5Buffer.reduce((a, str) => a + str.length, 0);\n  for (const value of Object.values(xrefInfo.info)) {\n    md5Buffer.push(value);\n    md5BufferLen += value.length;\n  }\n  const array = new Uint8Array(md5BufferLen);\n  let offset = 0;\n  for (const str of md5Buffer) {\n    writeString(str, offset, array);\n    offset += str.length;\n  }\n  return bytesToString(calculateMD5(array));\n}\nfunction writeXFADataForAcroform(str, newRefs) {\n  const xml = new SimpleXMLParser({\n    hasAttributes: true\n  }).parseFromString(str);\n  for (const {\n    xfa\n  } of newRefs) {\n    if (!xfa) {\n      continue;\n    }\n    const {\n      path,\n      value\n    } = xfa;\n    if (!path) {\n      continue;\n    }\n    const nodePath = parseXFAPath(path);\n    let node = xml.documentElement.searchNode(nodePath, 0);\n    if (!node && nodePath.length > 1) {\n      node = xml.documentElement.searchNode([nodePath.at(-1)], 0);\n    }\n    if (node) {\n      node.childNodes = Array.isArray(value) ? value.map(val => new SimpleDOMNode(\"value\", val)) : [new SimpleDOMNode(\"#text\", value)];\n    } else {\n      warn(`Node not found for path: ${path}`);\n    }\n  }\n  const buffer = [];\n  xml.documentElement.dump(buffer);\n  return buffer.join(\"\");\n}\nasync function updateAcroform({\n  xref,\n  acroForm,\n  acroFormRef,\n  hasXfa,\n  hasXfaDatasetsEntry,\n  xfaDatasetsRef,\n  needAppearances,\n  newRefs\n}) {\n  if (hasXfa && !hasXfaDatasetsEntry && !xfaDatasetsRef) {\n    warn(\"XFA - Cannot save it\");\n  }\n  if (!needAppearances && (!hasXfa || !xfaDatasetsRef || hasXfaDatasetsEntry)) {\n    return;\n  }\n  const dict = acroForm.clone();\n  if (hasXfa && !hasXfaDatasetsEntry) {\n    const newXfa = acroForm.get(\"XFA\").slice();\n    newXfa.splice(2, 0, \"datasets\");\n    newXfa.splice(3, 0, xfaDatasetsRef);\n    dict.set(\"XFA\", newXfa);\n  }\n  if (needAppearances) {\n    dict.set(\"NeedAppearances\", true);\n  }\n  const buffer = [];\n  await writeObject(acroFormRef, dict, buffer, xref);\n  newRefs.push({\n    ref: acroFormRef,\n    data: buffer.join(\"\")\n  });\n}\nfunction updateXFA({\n  xfaData,\n  xfaDatasetsRef,\n  newRefs,\n  xref\n}) {\n  if (xfaData === null) {\n    const datasets = xref.fetchIfRef(xfaDatasetsRef);\n    xfaData = writeXFADataForAcroform(datasets.getString(), newRefs);\n  }\n  const encrypt = xref.encrypt;\n  if (encrypt) {\n    const transform = encrypt.createCipherTransform(xfaDatasetsRef.num, xfaDatasetsRef.gen);\n    xfaData = transform.encryptString(xfaData);\n  }\n  const data = `${xfaDatasetsRef.num} ${xfaDatasetsRef.gen} obj\\n` + `<< /Type /EmbeddedFile /Length ${xfaData.length}>>\\nstream\\n` + xfaData + \"\\nendstream\\nendobj\\n\";\n  newRefs.push({\n    ref: xfaDatasetsRef,\n    data\n  });\n}\nasync function getXRefTable(xrefInfo, baseOffset, newRefs, newXref, buffer) {\n  buffer.push(\"xref\\n\");\n  const indexes = getIndexes(newRefs);\n  let indexesPosition = 0;\n  for (const {\n    ref,\n    data\n  } of newRefs) {\n    if (ref.num === indexes[indexesPosition]) {\n      buffer.push(`${indexes[indexesPosition]} ${indexes[indexesPosition + 1]}\\n`);\n      indexesPosition += 2;\n    }\n    buffer.push(`${baseOffset.toString().padStart(10, \"0\")} ${Math.min(ref.gen, 0xffff).toString().padStart(5, \"0\")} n\\r\\n`);\n    baseOffset += data.length;\n  }\n  computeIDs(baseOffset, xrefInfo, newXref);\n  buffer.push(\"trailer\\n\");\n  await writeDict(newXref, buffer);\n  buffer.push(\"\\nstartxref\\n\", baseOffset.toString(), \"\\n%%EOF\\n\");\n}\nfunction getIndexes(newRefs) {\n  const indexes = [];\n  for (const {\n    ref\n  } of newRefs) {\n    if (ref.num === indexes.at(-2) + indexes.at(-1)) {\n      indexes[indexes.length - 1] += 1;\n    } else {\n      indexes.push(ref.num, 1);\n    }\n  }\n  return indexes;\n}\nasync function getXRefStreamTable(xrefInfo, baseOffset, newRefs, newXref, buffer) {\n  const xrefTableData = [];\n  let maxOffset = 0;\n  let maxGen = 0;\n  for (const {\n    ref,\n    data\n  } of newRefs) {\n    maxOffset = Math.max(maxOffset, baseOffset);\n    const gen = Math.min(ref.gen, 0xffff);\n    maxGen = Math.max(maxGen, gen);\n    xrefTableData.push([1, baseOffset, gen]);\n    baseOffset += data.length;\n  }\n  newXref.set(\"Index\", getIndexes(newRefs));\n  const offsetSize = getSizeInBytes(maxOffset);\n  const maxGenSize = getSizeInBytes(maxGen);\n  const sizes = [1, offsetSize, maxGenSize];\n  newXref.set(\"W\", sizes);\n  computeIDs(baseOffset, xrefInfo, newXref);\n  const structSize = sizes.reduce((a, x) => a + x, 0);\n  const data = new Uint8Array(structSize * xrefTableData.length);\n  const stream = new Stream(data);\n  stream.dict = newXref;\n  let offset = 0;\n  for (const [type, objOffset, gen] of xrefTableData) {\n    offset = writeInt(type, sizes[0], offset, data);\n    offset = writeInt(objOffset, sizes[1], offset, data);\n    offset = writeInt(gen, sizes[2], offset, data);\n  }\n  await writeObject(xrefInfo.newRef, stream, buffer, {});\n  buffer.push(\"startxref\\n\", baseOffset.toString(), \"\\n%%EOF\\n\");\n}\nfunction computeIDs(baseOffset, xrefInfo, newXref) {\n  if (Array.isArray(xrefInfo.fileIds) && xrefInfo.fileIds.length > 0) {\n    const md5 = computeMD5(baseOffset, xrefInfo);\n    newXref.set(\"ID\", [xrefInfo.fileIds[0], md5]);\n  }\n}\nfunction getTrailerDict(xrefInfo, newRefs, useXrefStream) {\n  const newXref = new Dict(null);\n  newXref.set(\"Prev\", xrefInfo.startXRef);\n  const refForXrefTable = xrefInfo.newRef;\n  if (useXrefStream) {\n    newRefs.push({\n      ref: refForXrefTable,\n      data: \"\"\n    });\n    newXref.set(\"Size\", refForXrefTable.num + 1);\n    newXref.set(\"Type\", Name.get(\"XRef\"));\n  } else {\n    newXref.set(\"Size\", refForXrefTable.num);\n  }\n  if (xrefInfo.rootRef !== null) {\n    newXref.set(\"Root\", xrefInfo.rootRef);\n  }\n  if (xrefInfo.infoRef !== null) {\n    newXref.set(\"Info\", xrefInfo.infoRef);\n  }\n  if (xrefInfo.encryptRef !== null) {\n    newXref.set(\"Encrypt\", xrefInfo.encryptRef);\n  }\n  return newXref;\n}\nasync function incrementalUpdate({\n  originalData,\n  xrefInfo,\n  newRefs,\n  xref = null,\n  hasXfa = false,\n  xfaDatasetsRef = null,\n  hasXfaDatasetsEntry = false,\n  needAppearances,\n  acroFormRef = null,\n  acroForm = null,\n  xfaData = null,\n  useXrefStream = false\n}) {\n  await updateAcroform({\n    xref,\n    acroForm,\n    acroFormRef,\n    hasXfa,\n    hasXfaDatasetsEntry,\n    xfaDatasetsRef,\n    needAppearances,\n    newRefs\n  });\n  if (hasXfa) {\n    updateXFA({\n      xfaData,\n      xfaDatasetsRef,\n      newRefs,\n      xref\n    });\n  }\n  let buffer, baseOffset;\n  const lastByte = originalData.at(-1);\n  if (lastByte === 0x0a || lastByte === 0x0d) {\n    buffer = [];\n    baseOffset = originalData.length;\n  } else {\n    buffer = [\"\\n\"];\n    baseOffset = originalData.length + 1;\n  }\n  const newXref = getTrailerDict(xrefInfo, newRefs, useXrefStream);\n  newRefs = newRefs.sort((a, b) => a.ref.num - b.ref.num);\n  for (const {\n    data\n  } of newRefs) {\n    buffer.push(data);\n  }\n  await (useXrefStream ? getXRefStreamTable(xrefInfo, baseOffset, newRefs, newXref, buffer) : getXRefTable(xrefInfo, baseOffset, newRefs, newXref, buffer));\n  const totalLength = buffer.reduce((a, str) => a + str.length, originalData.length);\n  const array = new Uint8Array(totalLength);\n  array.set(originalData);\n  let offset = originalData.length;\n  for (const str of buffer) {\n    writeString(str, offset, array);\n    offset += str.length;\n  }\n  return array;\n}\n\n;// ./src/core/struct_tree.js\n\n\n\n\nconst MAX_DEPTH = 40;\nconst StructElementType = {\n  PAGE_CONTENT: 1,\n  STREAM_CONTENT: 2,\n  OBJECT: 3,\n  ANNOTATION: 4,\n  ELEMENT: 5\n};\nclass StructTreeRoot {\n  constructor(rootDict, rootRef) {\n    this.dict = rootDict;\n    this.ref = rootRef instanceof Ref ? rootRef : null;\n    this.roleMap = new Map();\n    this.structParentIds = null;\n  }\n  init() {\n    this.readRoleMap();\n  }\n  #addIdToPage(pageRef, id, type) {\n    if (!(pageRef instanceof Ref) || id < 0) {\n      return;\n    }\n    this.structParentIds ||= new RefSetCache();\n    let ids = this.structParentIds.get(pageRef);\n    if (!ids) {\n      ids = [];\n      this.structParentIds.put(pageRef, ids);\n    }\n    ids.push([id, type]);\n  }\n  addAnnotationIdToPage(pageRef, id) {\n    this.#addIdToPage(pageRef, id, StructElementType.ANNOTATION);\n  }\n  readRoleMap() {\n    const roleMapDict = this.dict.get(\"RoleMap\");\n    if (!(roleMapDict instanceof Dict)) {\n      return;\n    }\n    roleMapDict.forEach((key, value) => {\n      if (!(value instanceof Name)) {\n        return;\n      }\n      this.roleMap.set(key, value.name);\n    });\n  }\n  static async canCreateStructureTree({\n    catalogRef,\n    pdfManager,\n    newAnnotationsByPage\n  }) {\n    if (!(catalogRef instanceof Ref)) {\n      warn(\"Cannot save the struct tree: no catalog reference.\");\n      return false;\n    }\n    let nextKey = 0;\n    let hasNothingToUpdate = true;\n    for (const [pageIndex, elements] of newAnnotationsByPage) {\n      const {\n        ref: pageRef\n      } = await pdfManager.getPage(pageIndex);\n      if (!(pageRef instanceof Ref)) {\n        warn(`Cannot save the struct tree: page ${pageIndex} has no ref.`);\n        hasNothingToUpdate = true;\n        break;\n      }\n      for (const element of elements) {\n        if (element.accessibilityData?.type) {\n          element.parentTreeId = nextKey++;\n          hasNothingToUpdate = false;\n        }\n      }\n    }\n    if (hasNothingToUpdate) {\n      for (const elements of newAnnotationsByPage.values()) {\n        for (const element of elements) {\n          delete element.parentTreeId;\n        }\n      }\n      return false;\n    }\n    return true;\n  }\n  static async createStructureTree({\n    newAnnotationsByPage,\n    xref,\n    catalogRef,\n    pdfManager,\n    newRefs\n  }) {\n    const root = pdfManager.catalog.cloneDict();\n    const structTreeRootRef = xref.getNewTemporaryRef();\n    root.set(\"StructTreeRoot\", structTreeRootRef);\n    const buffer = [];\n    await writeObject(catalogRef, root, buffer, xref);\n    newRefs.push({\n      ref: catalogRef,\n      data: buffer.join(\"\")\n    });\n    const structTreeRoot = new Dict(xref);\n    structTreeRoot.set(\"Type\", Name.get(\"StructTreeRoot\"));\n    const parentTreeRef = xref.getNewTemporaryRef();\n    structTreeRoot.set(\"ParentTree\", parentTreeRef);\n    const kids = [];\n    structTreeRoot.set(\"K\", kids);\n    const parentTree = new Dict(xref);\n    const nums = [];\n    parentTree.set(\"Nums\", nums);\n    const nextKey = await this.#writeKids({\n      newAnnotationsByPage,\n      structTreeRootRef,\n      kids,\n      nums,\n      xref,\n      pdfManager,\n      newRefs,\n      buffer\n    });\n    structTreeRoot.set(\"ParentTreeNextKey\", nextKey);\n    buffer.length = 0;\n    await writeObject(parentTreeRef, parentTree, buffer, xref);\n    newRefs.push({\n      ref: parentTreeRef,\n      data: buffer.join(\"\")\n    });\n    buffer.length = 0;\n    await writeObject(structTreeRootRef, structTreeRoot, buffer, xref);\n    newRefs.push({\n      ref: structTreeRootRef,\n      data: buffer.join(\"\")\n    });\n  }\n  async canUpdateStructTree({\n    pdfManager,\n    xref,\n    newAnnotationsByPage\n  }) {\n    if (!this.ref) {\n      warn(\"Cannot update the struct tree: no root reference.\");\n      return false;\n    }\n    let nextKey = this.dict.get(\"ParentTreeNextKey\");\n    if (!Number.isInteger(nextKey) || nextKey < 0) {\n      warn(\"Cannot update the struct tree: invalid next key.\");\n      return false;\n    }\n    const parentTree = this.dict.get(\"ParentTree\");\n    if (!(parentTree instanceof Dict)) {\n      warn(\"Cannot update the struct tree: ParentTree isn't a dict.\");\n      return false;\n    }\n    const nums = parentTree.get(\"Nums\");\n    if (!Array.isArray(nums)) {\n      warn(\"Cannot update the struct tree: nums isn't an array.\");\n      return false;\n    }\n    const numberTree = new NumberTree(parentTree, xref);\n    for (const pageIndex of newAnnotationsByPage.keys()) {\n      const {\n        pageDict\n      } = await pdfManager.getPage(pageIndex);\n      if (!pageDict.has(\"StructParents\")) {\n        continue;\n      }\n      const id = pageDict.get(\"StructParents\");\n      if (!Number.isInteger(id) || !Array.isArray(numberTree.get(id))) {\n        warn(`Cannot save the struct tree: page ${pageIndex} has a wrong id.`);\n        return false;\n      }\n    }\n    let hasNothingToUpdate = true;\n    for (const [pageIndex, elements] of newAnnotationsByPage) {\n      const {\n        pageDict\n      } = await pdfManager.getPage(pageIndex);\n      StructTreeRoot.#collectParents({\n        elements,\n        xref: this.dict.xref,\n        pageDict,\n        numberTree\n      });\n      for (const element of elements) {\n        if (element.accessibilityData?.type) {\n          element.parentTreeId = nextKey++;\n          hasNothingToUpdate = false;\n        }\n      }\n    }\n    if (hasNothingToUpdate) {\n      for (const elements of newAnnotationsByPage.values()) {\n        for (const element of elements) {\n          delete element.parentTreeId;\n          delete element.structTreeParent;\n        }\n      }\n      return false;\n    }\n    return true;\n  }\n  async updateStructureTree({\n    newAnnotationsByPage,\n    pdfManager,\n    newRefs\n  }) {\n    const xref = this.dict.xref;\n    const structTreeRoot = this.dict.clone();\n    const structTreeRootRef = this.ref;\n    let parentTreeRef = structTreeRoot.getRaw(\"ParentTree\");\n    let parentTree;\n    if (parentTreeRef instanceof Ref) {\n      parentTree = xref.fetch(parentTreeRef);\n    } else {\n      parentTree = parentTreeRef;\n      parentTreeRef = xref.getNewTemporaryRef();\n      structTreeRoot.set(\"ParentTree\", parentTreeRef);\n    }\n    parentTree = parentTree.clone();\n    let nums = parentTree.getRaw(\"Nums\");\n    let numsRef = null;\n    if (nums instanceof Ref) {\n      numsRef = nums;\n      nums = xref.fetch(numsRef);\n    }\n    nums = nums.slice();\n    if (!numsRef) {\n      parentTree.set(\"Nums\", nums);\n    }\n    let kids = structTreeRoot.getRaw(\"K\");\n    let kidsRef = null;\n    if (kids instanceof Ref) {\n      kidsRef = kids;\n      kids = xref.fetch(kidsRef);\n    } else {\n      kidsRef = xref.getNewTemporaryRef();\n      structTreeRoot.set(\"K\", kidsRef);\n    }\n    kids = Array.isArray(kids) ? kids.slice() : [kids];\n    const buffer = [];\n    const newNextkey = await StructTreeRoot.#writeKids({\n      newAnnotationsByPage,\n      structTreeRootRef,\n      kids,\n      nums,\n      xref,\n      pdfManager,\n      newRefs,\n      buffer\n    });\n    structTreeRoot.set(\"ParentTreeNextKey\", newNextkey);\n    buffer.length = 0;\n    await writeObject(kidsRef, kids, buffer, xref);\n    newRefs.push({\n      ref: kidsRef,\n      data: buffer.join(\"\")\n    });\n    if (numsRef) {\n      buffer.length = 0;\n      await writeObject(numsRef, nums, buffer, xref);\n      newRefs.push({\n        ref: numsRef,\n        data: buffer.join(\"\")\n      });\n    }\n    buffer.length = 0;\n    await writeObject(parentTreeRef, parentTree, buffer, xref);\n    newRefs.push({\n      ref: parentTreeRef,\n      data: buffer.join(\"\")\n    });\n    buffer.length = 0;\n    await writeObject(structTreeRootRef, structTreeRoot, buffer, xref);\n    newRefs.push({\n      ref: structTreeRootRef,\n      data: buffer.join(\"\")\n    });\n  }\n  static async #writeKids({\n    newAnnotationsByPage,\n    structTreeRootRef,\n    kids,\n    nums,\n    xref,\n    pdfManager,\n    newRefs,\n    buffer\n  }) {\n    const objr = Name.get(\"OBJR\");\n    let nextKey = -Infinity;\n    for (const [pageIndex, elements] of newAnnotationsByPage) {\n      const {\n        ref: pageRef\n      } = await pdfManager.getPage(pageIndex);\n      const isPageRef = pageRef instanceof Ref;\n      for (const {\n        accessibilityData,\n        ref,\n        parentTreeId,\n        structTreeParent\n      } of elements) {\n        if (!accessibilityData?.type) {\n          continue;\n        }\n        const {\n          type,\n          title,\n          lang,\n          alt,\n          expanded,\n          actualText\n        } = accessibilityData;\n        nextKey = Math.max(nextKey, parentTreeId);\n        const tagRef = xref.getNewTemporaryRef();\n        const tagDict = new Dict(xref);\n        tagDict.set(\"S\", Name.get(type));\n        if (title) {\n          tagDict.set(\"T\", title);\n        }\n        if (lang) {\n          tagDict.set(\"Lang\", lang);\n        }\n        if (alt) {\n          tagDict.set(\"Alt\", alt);\n        }\n        if (expanded) {\n          tagDict.set(\"E\", expanded);\n        }\n        if (actualText) {\n          tagDict.set(\"ActualText\", actualText);\n        }\n        if (structTreeParent) {\n          await this.#updateParentTag({\n            structTreeParent,\n            tagDict,\n            newTagRef: tagRef,\n            fallbackRef: structTreeRootRef,\n            xref,\n            newRefs,\n            buffer\n          });\n        } else {\n          tagDict.set(\"P\", structTreeRootRef);\n        }\n        const objDict = new Dict(xref);\n        tagDict.set(\"K\", objDict);\n        objDict.set(\"Type\", objr);\n        if (isPageRef) {\n          objDict.set(\"Pg\", pageRef);\n        }\n        objDict.set(\"Obj\", ref);\n        buffer.length = 0;\n        await writeObject(tagRef, tagDict, buffer, xref);\n        newRefs.push({\n          ref: tagRef,\n          data: buffer.join(\"\")\n        });\n        nums.push(parentTreeId, tagRef);\n        kids.push(tagRef);\n      }\n    }\n    return nextKey + 1;\n  }\n  static #collectParents({\n    elements,\n    xref,\n    pageDict,\n    numberTree\n  }) {\n    const idToElement = new Map();\n    for (const element of elements) {\n      if (element.structTreeParentId) {\n        const id = parseInt(element.structTreeParentId.split(\"_mc\")[1], 10);\n        idToElement.set(id, element);\n      }\n    }\n    const id = pageDict.get(\"StructParents\");\n    if (!Number.isInteger(id)) {\n      return;\n    }\n    const parentArray = numberTree.get(id);\n    const updateElement = (kid, pageKid, kidRef) => {\n      const element = idToElement.get(kid);\n      if (element) {\n        const parentRef = pageKid.getRaw(\"P\");\n        const parentDict = xref.fetchIfRef(parentRef);\n        if (parentRef instanceof Ref && parentDict instanceof Dict) {\n          element.structTreeParent = {\n            ref: kidRef,\n            dict: pageKid\n          };\n        }\n        return true;\n      }\n      return false;\n    };\n    for (const kidRef of parentArray) {\n      if (!(kidRef instanceof Ref)) {\n        continue;\n      }\n      const pageKid = xref.fetch(kidRef);\n      const k = pageKid.get(\"K\");\n      if (Number.isInteger(k)) {\n        updateElement(k, pageKid, kidRef);\n        continue;\n      }\n      if (!Array.isArray(k)) {\n        continue;\n      }\n      for (let kid of k) {\n        kid = xref.fetchIfRef(kid);\n        if (Number.isInteger(kid) && updateElement(kid, pageKid, kidRef)) {\n          break;\n        }\n      }\n    }\n  }\n  static async #updateParentTag({\n    structTreeParent: {\n      ref,\n      dict\n    },\n    tagDict,\n    newTagRef,\n    fallbackRef,\n    xref,\n    newRefs,\n    buffer\n  }) {\n    const parentRef = dict.getRaw(\"P\");\n    let parentDict = xref.fetchIfRef(parentRef);\n    tagDict.set(\"P\", parentRef);\n    let saveParentDict = false;\n    let parentKids;\n    let parentKidsRef = parentDict.getRaw(\"K\");\n    if (!(parentKidsRef instanceof Ref)) {\n      parentKids = parentKidsRef;\n      parentKidsRef = xref.getNewTemporaryRef();\n      parentDict = parentDict.clone();\n      parentDict.set(\"K\", parentKidsRef);\n      saveParentDict = true;\n    } else {\n      parentKids = xref.fetch(parentKidsRef);\n    }\n    if (Array.isArray(parentKids)) {\n      const index = parentKids.indexOf(ref);\n      if (index >= 0) {\n        parentKids = parentKids.slice();\n        parentKids.splice(index + 1, 0, newTagRef);\n      } else {\n        warn(\"Cannot update the struct tree: parent kid not found.\");\n        tagDict.set(\"P\", fallbackRef);\n        return;\n      }\n    } else if (parentKids instanceof Dict) {\n      parentKids = [parentKidsRef, newTagRef];\n      parentKidsRef = xref.getNewTemporaryRef();\n      parentDict.set(\"K\", parentKidsRef);\n      saveParentDict = true;\n    }\n    buffer.length = 0;\n    await writeObject(parentKidsRef, parentKids, buffer, xref);\n    newRefs.push({\n      ref: parentKidsRef,\n      data: buffer.join(\"\")\n    });\n    if (!saveParentDict) {\n      return;\n    }\n    buffer.length = 0;\n    await writeObject(parentRef, parentDict, buffer, xref);\n    newRefs.push({\n      ref: parentRef,\n      data: buffer.join(\"\")\n    });\n  }\n}\nclass StructElementNode {\n  constructor(tree, dict) {\n    this.tree = tree;\n    this.dict = dict;\n    this.kids = [];\n    this.parseKids();\n  }\n  get role() {\n    const nameObj = this.dict.get(\"S\");\n    const name = nameObj instanceof Name ? nameObj.name : \"\";\n    const {\n      root\n    } = this.tree;\n    if (root.roleMap.has(name)) {\n      return root.roleMap.get(name);\n    }\n    return name;\n  }\n  parseKids() {\n    let pageObjId = null;\n    const objRef = this.dict.getRaw(\"Pg\");\n    if (objRef instanceof Ref) {\n      pageObjId = objRef.toString();\n    }\n    const kids = this.dict.get(\"K\");\n    if (Array.isArray(kids)) {\n      for (const kid of kids) {\n        const element = this.parseKid(pageObjId, kid);\n        if (element) {\n          this.kids.push(element);\n        }\n      }\n    } else {\n      const element = this.parseKid(pageObjId, kids);\n      if (element) {\n        this.kids.push(element);\n      }\n    }\n  }\n  parseKid(pageObjId, kid) {\n    if (Number.isInteger(kid)) {\n      if (this.tree.pageDict.objId !== pageObjId) {\n        return null;\n      }\n      return new StructElement({\n        type: StructElementType.PAGE_CONTENT,\n        mcid: kid,\n        pageObjId\n      });\n    }\n    let kidDict = null;\n    if (kid instanceof Ref) {\n      kidDict = this.dict.xref.fetch(kid);\n    } else if (kid instanceof Dict) {\n      kidDict = kid;\n    }\n    if (!kidDict) {\n      return null;\n    }\n    const pageRef = kidDict.getRaw(\"Pg\");\n    if (pageRef instanceof Ref) {\n      pageObjId = pageRef.toString();\n    }\n    const type = kidDict.get(\"Type\") instanceof Name ? kidDict.get(\"Type\").name : null;\n    if (type === \"MCR\") {\n      if (this.tree.pageDict.objId !== pageObjId) {\n        return null;\n      }\n      const kidRef = kidDict.getRaw(\"Stm\");\n      return new StructElement({\n        type: StructElementType.STREAM_CONTENT,\n        refObjId: kidRef instanceof Ref ? kidRef.toString() : null,\n        pageObjId,\n        mcid: kidDict.get(\"MCID\")\n      });\n    }\n    if (type === \"OBJR\") {\n      if (this.tree.pageDict.objId !== pageObjId) {\n        return null;\n      }\n      const kidRef = kidDict.getRaw(\"Obj\");\n      return new StructElement({\n        type: StructElementType.OBJECT,\n        refObjId: kidRef instanceof Ref ? kidRef.toString() : null,\n        pageObjId\n      });\n    }\n    return new StructElement({\n      type: StructElementType.ELEMENT,\n      dict: kidDict\n    });\n  }\n}\nclass StructElement {\n  constructor({\n    type,\n    dict = null,\n    mcid = null,\n    pageObjId = null,\n    refObjId = null\n  }) {\n    this.type = type;\n    this.dict = dict;\n    this.mcid = mcid;\n    this.pageObjId = pageObjId;\n    this.refObjId = refObjId;\n    this.parentNode = null;\n  }\n}\nclass StructTreePage {\n  constructor(structTreeRoot, pageDict) {\n    this.root = structTreeRoot;\n    this.rootDict = structTreeRoot ? structTreeRoot.dict : null;\n    this.pageDict = pageDict;\n    this.nodes = [];\n  }\n  parse(pageRef) {\n    if (!this.root || !this.rootDict) {\n      return;\n    }\n    const parentTree = this.rootDict.get(\"ParentTree\");\n    if (!parentTree) {\n      return;\n    }\n    const id = this.pageDict.get(\"StructParents\");\n    const ids = pageRef instanceof Ref && this.root.structParentIds?.get(pageRef);\n    if (!Number.isInteger(id) && !ids) {\n      return;\n    }\n    const map = new Map();\n    const numberTree = new NumberTree(parentTree, this.rootDict.xref);\n    if (Number.isInteger(id)) {\n      const parentArray = numberTree.get(id);\n      if (Array.isArray(parentArray)) {\n        for (const ref of parentArray) {\n          if (ref instanceof Ref) {\n            this.addNode(this.rootDict.xref.fetch(ref), map);\n          }\n        }\n      }\n    }\n    if (!ids) {\n      return;\n    }\n    for (const [elemId, type] of ids) {\n      const obj = numberTree.get(elemId);\n      if (obj) {\n        const elem = this.addNode(this.rootDict.xref.fetchIfRef(obj), map);\n        if (elem?.kids?.length === 1 && elem.kids[0].type === StructElementType.OBJECT) {\n          elem.kids[0].type = type;\n        }\n      }\n    }\n  }\n  addNode(dict, map, level = 0) {\n    if (level > MAX_DEPTH) {\n      warn(\"StructTree MAX_DEPTH reached.\");\n      return null;\n    }\n    if (map.has(dict)) {\n      return map.get(dict);\n    }\n    const element = new StructElementNode(this, dict);\n    map.set(dict, element);\n    const parent = dict.get(\"P\");\n    if (!parent || isName(parent.get(\"Type\"), \"StructTreeRoot\")) {\n      if (!this.addTopLevelNode(dict, element)) {\n        map.delete(dict);\n      }\n      return element;\n    }\n    const parentNode = this.addNode(parent, map, level + 1);\n    if (!parentNode) {\n      return element;\n    }\n    let save = false;\n    for (const kid of parentNode.kids) {\n      if (kid.type === StructElementType.ELEMENT && kid.dict === dict) {\n        kid.parentNode = element;\n        save = true;\n      }\n    }\n    if (!save) {\n      map.delete(dict);\n    }\n    return element;\n  }\n  addTopLevelNode(dict, element) {\n    const obj = this.rootDict.get(\"K\");\n    if (!obj) {\n      return false;\n    }\n    if (obj instanceof Dict) {\n      if (obj.objId !== dict.objId) {\n        return false;\n      }\n      this.nodes[0] = element;\n      return true;\n    }\n    if (!Array.isArray(obj)) {\n      return true;\n    }\n    let save = false;\n    for (let i = 0; i < obj.length; i++) {\n      const kidRef = obj[i];\n      if (kidRef?.toString() === dict.objId) {\n        this.nodes[i] = element;\n        save = true;\n      }\n    }\n    return save;\n  }\n  get serializable() {\n    function nodeToSerializable(node, parent, level = 0) {\n      if (level > MAX_DEPTH) {\n        warn(\"StructTree too deep to be fully serialized.\");\n        return;\n      }\n      const obj = Object.create(null);\n      obj.role = node.role;\n      obj.children = [];\n      parent.children.push(obj);\n      const alt = node.dict.get(\"Alt\");\n      if (typeof alt === \"string\") {\n        obj.alt = stringToPDFString(alt);\n      }\n      const lang = node.dict.get(\"Lang\");\n      if (typeof lang === \"string\") {\n        obj.lang = stringToPDFString(lang);\n      }\n      for (const kid of node.kids) {\n        const kidElement = kid.type === StructElementType.ELEMENT ? kid.parentNode : null;\n        if (kidElement) {\n          nodeToSerializable(kidElement, obj, level + 1);\n          continue;\n        } else if (kid.type === StructElementType.PAGE_CONTENT || kid.type === StructElementType.STREAM_CONTENT) {\n          obj.children.push({\n            type: \"content\",\n            id: `p${kid.pageObjId}_mc${kid.mcid}`\n          });\n        } else if (kid.type === StructElementType.OBJECT) {\n          obj.children.push({\n            type: \"object\",\n            id: kid.refObjId\n          });\n        } else if (kid.type === StructElementType.ANNOTATION) {\n          obj.children.push({\n            type: \"annotation\",\n            id: `${AnnotationPrefix}${kid.refObjId}`\n          });\n        }\n      }\n    }\n    const root = Object.create(null);\n    root.children = [];\n    root.role = \"Root\";\n    for (const child of this.nodes) {\n      if (!child) {\n        continue;\n      }\n      nodeToSerializable(child, root);\n    }\n    return root;\n  }\n}\n\n;// ./src/core/catalog.js\n\n\n\n\n\n\n\n\n\n\n\nfunction fetchDestination(dest) {\n  if (dest instanceof Dict) {\n    dest = dest.get(\"D\");\n  }\n  return Array.isArray(dest) ? dest : null;\n}\nfunction fetchRemoteDest(action) {\n  let dest = action.get(\"D\");\n  if (dest) {\n    if (dest instanceof Name) {\n      dest = dest.name;\n    }\n    if (typeof dest === \"string\") {\n      return stringToPDFString(dest);\n    } else if (Array.isArray(dest)) {\n      return JSON.stringify(dest);\n    }\n  }\n  return null;\n}\nclass Catalog {\n  constructor(pdfManager, xref) {\n    this.pdfManager = pdfManager;\n    this.xref = xref;\n    this._catDict = xref.getCatalogObj();\n    if (!(this._catDict instanceof Dict)) {\n      throw new FormatError(\"Catalog object is not a dictionary.\");\n    }\n    this.toplevelPagesDict;\n    this._actualNumPages = null;\n    this.fontCache = new RefSetCache();\n    this.builtInCMapCache = new Map();\n    this.standardFontDataCache = new Map();\n    this.globalImageCache = new GlobalImageCache();\n    this.pageKidsCountCache = new RefSetCache();\n    this.pageIndexCache = new RefSetCache();\n    this.nonBlendModesSet = new RefSet();\n    this.systemFontCache = new Map();\n  }\n  cloneDict() {\n    return this._catDict.clone();\n  }\n  get version() {\n    const version = this._catDict.get(\"Version\");\n    if (version instanceof Name) {\n      if (PDF_VERSION_REGEXP.test(version.name)) {\n        return shadow(this, \"version\", version.name);\n      }\n      warn(`Invalid PDF catalog version: ${version.name}`);\n    }\n    return shadow(this, \"version\", null);\n  }\n  get lang() {\n    const lang = this._catDict.get(\"Lang\");\n    return shadow(this, \"lang\", typeof lang === \"string\" ? stringToPDFString(lang) : null);\n  }\n  get needsRendering() {\n    const needsRendering = this._catDict.get(\"NeedsRendering\");\n    return shadow(this, \"needsRendering\", typeof needsRendering === \"boolean\" ? needsRendering : false);\n  }\n  get collection() {\n    let collection = null;\n    try {\n      const obj = this._catDict.get(\"Collection\");\n      if (obj instanceof Dict && obj.size > 0) {\n        collection = obj;\n      }\n    } catch (ex) {\n      if (ex instanceof MissingDataException) {\n        throw ex;\n      }\n      info(\"Cannot fetch Collection entry; assuming no collection is present.\");\n    }\n    return shadow(this, \"collection\", collection);\n  }\n  get acroForm() {\n    let acroForm = null;\n    try {\n      const obj = this._catDict.get(\"AcroForm\");\n      if (obj instanceof Dict && obj.size > 0) {\n        acroForm = obj;\n      }\n    } catch (ex) {\n      if (ex instanceof MissingDataException) {\n        throw ex;\n      }\n      info(\"Cannot fetch AcroForm entry; assuming no forms are present.\");\n    }\n    return shadow(this, \"acroForm\", acroForm);\n  }\n  get acroFormRef() {\n    const value = this._catDict.getRaw(\"AcroForm\");\n    return shadow(this, \"acroFormRef\", value instanceof Ref ? value : null);\n  }\n  get metadata() {\n    const streamRef = this._catDict.getRaw(\"Metadata\");\n    if (!(streamRef instanceof Ref)) {\n      return shadow(this, \"metadata\", null);\n    }\n    let metadata = null;\n    try {\n      const stream = this.xref.fetch(streamRef, !this.xref.encrypt?.encryptMetadata);\n      if (stream instanceof BaseStream && stream.dict instanceof Dict) {\n        const type = stream.dict.get(\"Type\");\n        const subtype = stream.dict.get(\"Subtype\");\n        if (isName(type, \"Metadata\") && isName(subtype, \"XML\")) {\n          const data = stringToUTF8String(stream.getString());\n          if (data) {\n            metadata = new MetadataParser(data).serializable;\n          }\n        }\n      }\n    } catch (ex) {\n      if (ex instanceof MissingDataException) {\n        throw ex;\n      }\n      info(`Skipping invalid Metadata: \"${ex}\".`);\n    }\n    return shadow(this, \"metadata\", metadata);\n  }\n  get markInfo() {\n    let markInfo = null;\n    try {\n      markInfo = this._readMarkInfo();\n    } catch (ex) {\n      if (ex instanceof MissingDataException) {\n        throw ex;\n      }\n      warn(\"Unable to read mark info.\");\n    }\n    return shadow(this, \"markInfo\", markInfo);\n  }\n  _readMarkInfo() {\n    const obj = this._catDict.get(\"MarkInfo\");\n    if (!(obj instanceof Dict)) {\n      return null;\n    }\n    const markInfo = {\n      Marked: false,\n      UserProperties: false,\n      Suspects: false\n    };\n    for (const key in markInfo) {\n      const value = obj.get(key);\n      if (typeof value === \"boolean\") {\n        markInfo[key] = value;\n      }\n    }\n    return markInfo;\n  }\n  get structTreeRoot() {\n    let structTree = null;\n    try {\n      structTree = this._readStructTreeRoot();\n    } catch (ex) {\n      if (ex instanceof MissingDataException) {\n        throw ex;\n      }\n      warn(\"Unable read to structTreeRoot info.\");\n    }\n    return shadow(this, \"structTreeRoot\", structTree);\n  }\n  _readStructTreeRoot() {\n    const rawObj = this._catDict.getRaw(\"StructTreeRoot\");\n    const obj = this.xref.fetchIfRef(rawObj);\n    if (!(obj instanceof Dict)) {\n      return null;\n    }\n    const root = new StructTreeRoot(obj, rawObj);\n    root.init();\n    return root;\n  }\n  get toplevelPagesDict() {\n    const pagesObj = this._catDict.get(\"Pages\");\n    if (!(pagesObj instanceof Dict)) {\n      throw new FormatError(\"Invalid top-level pages dictionary.\");\n    }\n    return shadow(this, \"toplevelPagesDict\", pagesObj);\n  }\n  get documentOutline() {\n    let obj = null;\n    try {\n      obj = this._readDocumentOutline();\n    } catch (ex) {\n      if (ex instanceof MissingDataException) {\n        throw ex;\n      }\n      warn(\"Unable to read document outline.\");\n    }\n    return shadow(this, \"documentOutline\", obj);\n  }\n  _readDocumentOutline() {\n    let obj = this._catDict.get(\"Outlines\");\n    if (!(obj instanceof Dict)) {\n      return null;\n    }\n    obj = obj.getRaw(\"First\");\n    if (!(obj instanceof Ref)) {\n      return null;\n    }\n    const root = {\n      items: []\n    };\n    const queue = [{\n      obj,\n      parent: root\n    }];\n    const processed = new RefSet();\n    processed.put(obj);\n    const xref = this.xref,\n      blackColor = new Uint8ClampedArray(3);\n    while (queue.length > 0) {\n      const i = queue.shift();\n      const outlineDict = xref.fetchIfRef(i.obj);\n      if (outlineDict === null) {\n        continue;\n      }\n      if (!outlineDict.has(\"Title\")) {\n        throw new FormatError(\"Invalid outline item encountered.\");\n      }\n      const data = {\n        url: null,\n        dest: null,\n        action: null\n      };\n      Catalog.parseDestDictionary({\n        destDict: outlineDict,\n        resultObj: data,\n        docBaseUrl: this.baseUrl,\n        docAttachments: this.attachments\n      });\n      const title = outlineDict.get(\"Title\");\n      const flags = outlineDict.get(\"F\") || 0;\n      const color = outlineDict.getArray(\"C\");\n      const count = outlineDict.get(\"Count\");\n      let rgbColor = blackColor;\n      if (Array.isArray(color) && color.length === 3 && (color[0] !== 0 || color[1] !== 0 || color[2] !== 0)) {\n        rgbColor = ColorSpace.singletons.rgb.getRgb(color, 0);\n      }\n      const outlineItem = {\n        action: data.action,\n        attachment: data.attachment,\n        dest: data.dest,\n        url: data.url,\n        unsafeUrl: data.unsafeUrl,\n        newWindow: data.newWindow,\n        setOCGState: data.setOCGState,\n        title: stringToPDFString(title),\n        color: rgbColor,\n        count: Number.isInteger(count) ? count : undefined,\n        bold: !!(flags & 2),\n        italic: !!(flags & 1),\n        items: []\n      };\n      i.parent.items.push(outlineItem);\n      obj = outlineDict.getRaw(\"First\");\n      if (obj instanceof Ref && !processed.has(obj)) {\n        queue.push({\n          obj,\n          parent: outlineItem\n        });\n        processed.put(obj);\n      }\n      obj = outlineDict.getRaw(\"Next\");\n      if (obj instanceof Ref && !processed.has(obj)) {\n        queue.push({\n          obj,\n          parent: i.parent\n        });\n        processed.put(obj);\n      }\n    }\n    return root.items.length > 0 ? root.items : null;\n  }\n  get permissions() {\n    let permissions = null;\n    try {\n      permissions = this._readPermissions();\n    } catch (ex) {\n      if (ex instanceof MissingDataException) {\n        throw ex;\n      }\n      warn(\"Unable to read permissions.\");\n    }\n    return shadow(this, \"permissions\", permissions);\n  }\n  _readPermissions() {\n    const encrypt = this.xref.trailer.get(\"Encrypt\");\n    if (!(encrypt instanceof Dict)) {\n      return null;\n    }\n    let flags = encrypt.get(\"P\");\n    if (typeof flags !== \"number\") {\n      return null;\n    }\n    flags += 2 ** 32;\n    const permissions = [];\n    for (const key in PermissionFlag) {\n      const value = PermissionFlag[key];\n      if (flags & value) {\n        permissions.push(value);\n      }\n    }\n    return permissions;\n  }\n  get optionalContentConfig() {\n    let config = null;\n    try {\n      const properties = this._catDict.get(\"OCProperties\");\n      if (!properties) {\n        return shadow(this, \"optionalContentConfig\", null);\n      }\n      const defaultConfig = properties.get(\"D\");\n      if (!defaultConfig) {\n        return shadow(this, \"optionalContentConfig\", null);\n      }\n      const groupsData = properties.get(\"OCGs\");\n      if (!Array.isArray(groupsData)) {\n        return shadow(this, \"optionalContentConfig\", null);\n      }\n      const groups = [];\n      const groupRefs = new RefSet();\n      for (const groupRef of groupsData) {\n        if (!(groupRef instanceof Ref) || groupRefs.has(groupRef)) {\n          continue;\n        }\n        groupRefs.put(groupRef);\n        groups.push(this.#readOptionalContentGroup(groupRef));\n      }\n      config = this.#readOptionalContentConfig(defaultConfig, groupRefs);\n      config.groups = groups;\n    } catch (ex) {\n      if (ex instanceof MissingDataException) {\n        throw ex;\n      }\n      warn(`Unable to read optional content config: ${ex}`);\n    }\n    return shadow(this, \"optionalContentConfig\", config);\n  }\n  #readOptionalContentGroup(groupRef) {\n    const group = this.xref.fetch(groupRef);\n    const obj = {\n      id: groupRef.toString(),\n      name: null,\n      intent: null,\n      usage: {\n        print: null,\n        view: null\n      }\n    };\n    const name = group.get(\"Name\");\n    if (typeof name === \"string\") {\n      obj.name = stringToPDFString(name);\n    }\n    let intent = group.getArray(\"Intent\");\n    if (!Array.isArray(intent)) {\n      intent = [intent];\n    }\n    if (intent.every(i => i instanceof Name)) {\n      obj.intent = intent.map(i => i.name);\n    }\n    const usage = group.get(\"Usage\");\n    if (!(usage instanceof Dict)) {\n      return obj;\n    }\n    const usageObj = obj.usage;\n    const print = usage.get(\"Print\");\n    if (print instanceof Dict) {\n      const printState = print.get(\"PrintState\");\n      if (printState instanceof Name) {\n        switch (printState.name) {\n          case \"ON\":\n          case \"OFF\":\n            usageObj.print = {\n              printState: printState.name\n            };\n        }\n      }\n    }\n    const view = usage.get(\"View\");\n    if (view instanceof Dict) {\n      const viewState = view.get(\"ViewState\");\n      if (viewState instanceof Name) {\n        switch (viewState.name) {\n          case \"ON\":\n          case \"OFF\":\n            usageObj.view = {\n              viewState: viewState.name\n            };\n        }\n      }\n    }\n    return obj;\n  }\n  #readOptionalContentConfig(config, contentGroupRefs) {\n    function parseOnOff(refs) {\n      const onParsed = [];\n      if (Array.isArray(refs)) {\n        for (const value of refs) {\n          if (!(value instanceof Ref)) {\n            continue;\n          }\n          if (contentGroupRefs.has(value)) {\n            onParsed.push(value.toString());\n          }\n        }\n      }\n      return onParsed;\n    }\n    function parseOrder(refs, nestedLevels = 0) {\n      if (!Array.isArray(refs)) {\n        return null;\n      }\n      const order = [];\n      for (const value of refs) {\n        if (value instanceof Ref && contentGroupRefs.has(value)) {\n          parsedOrderRefs.put(value);\n          order.push(value.toString());\n          continue;\n        }\n        const nestedOrder = parseNestedOrder(value, nestedLevels);\n        if (nestedOrder) {\n          order.push(nestedOrder);\n        }\n      }\n      if (nestedLevels > 0) {\n        return order;\n      }\n      const hiddenGroups = [];\n      for (const groupRef of contentGroupRefs) {\n        if (parsedOrderRefs.has(groupRef)) {\n          continue;\n        }\n        hiddenGroups.push(groupRef.toString());\n      }\n      if (hiddenGroups.length) {\n        order.push({\n          name: null,\n          order: hiddenGroups\n        });\n      }\n      return order;\n    }\n    function parseNestedOrder(ref, nestedLevels) {\n      if (++nestedLevels > MAX_NESTED_LEVELS) {\n        warn(\"parseNestedOrder - reached MAX_NESTED_LEVELS.\");\n        return null;\n      }\n      const value = xref.fetchIfRef(ref);\n      if (!Array.isArray(value)) {\n        return null;\n      }\n      const nestedName = xref.fetchIfRef(value[0]);\n      if (typeof nestedName !== \"string\") {\n        return null;\n      }\n      const nestedOrder = parseOrder(value.slice(1), nestedLevels);\n      if (!nestedOrder || !nestedOrder.length) {\n        return null;\n      }\n      return {\n        name: stringToPDFString(nestedName),\n        order: nestedOrder\n      };\n    }\n    const xref = this.xref,\n      parsedOrderRefs = new RefSet(),\n      MAX_NESTED_LEVELS = 10;\n    return {\n      name: typeof config.get(\"Name\") === \"string\" ? stringToPDFString(config.get(\"Name\")) : null,\n      creator: typeof config.get(\"Creator\") === \"string\" ? stringToPDFString(config.get(\"Creator\")) : null,\n      baseState: config.get(\"BaseState\") instanceof Name ? config.get(\"BaseState\").name : null,\n      on: parseOnOff(config.get(\"ON\")),\n      off: parseOnOff(config.get(\"OFF\")),\n      order: parseOrder(config.get(\"Order\")),\n      groups: null\n    };\n  }\n  setActualNumPages(num = null) {\n    this._actualNumPages = num;\n  }\n  get hasActualNumPages() {\n    return this._actualNumPages !== null;\n  }\n  get _pagesCount() {\n    const obj = this.toplevelPagesDict.get(\"Count\");\n    if (!Number.isInteger(obj)) {\n      throw new FormatError(\"Page count in top-level pages dictionary is not an integer.\");\n    }\n    return shadow(this, \"_pagesCount\", obj);\n  }\n  get numPages() {\n    return this.hasActualNumPages ? this._actualNumPages : this._pagesCount;\n  }\n  get destinations() {\n    const obj = this._readDests(),\n      dests = Object.create(null);\n    if (obj instanceof NameTree) {\n      for (const [key, value] of obj.getAll()) {\n        const dest = fetchDestination(value);\n        if (dest) {\n          dests[stringToPDFString(key)] = dest;\n        }\n      }\n    } else if (obj instanceof Dict) {\n      obj.forEach(function (key, value) {\n        const dest = fetchDestination(value);\n        if (dest) {\n          dests[key] = dest;\n        }\n      });\n    }\n    return shadow(this, \"destinations\", dests);\n  }\n  getDestination(id) {\n    const obj = this._readDests();\n    if (obj instanceof NameTree) {\n      const dest = fetchDestination(obj.get(id));\n      if (dest) {\n        return dest;\n      }\n      const allDest = this.destinations[id];\n      if (allDest) {\n        warn(`Found \"${id}\" at an incorrect position in the NameTree.`);\n        return allDest;\n      }\n    } else if (obj instanceof Dict) {\n      const dest = fetchDestination(obj.get(id));\n      if (dest) {\n        return dest;\n      }\n    }\n    return null;\n  }\n  _readDests() {\n    const obj = this._catDict.get(\"Names\");\n    if (obj?.has(\"Dests\")) {\n      return new NameTree(obj.getRaw(\"Dests\"), this.xref);\n    } else if (this._catDict.has(\"Dests\")) {\n      return this._catDict.get(\"Dests\");\n    }\n    return undefined;\n  }\n  get pageLabels() {\n    let obj = null;\n    try {\n      obj = this._readPageLabels();\n    } catch (ex) {\n      if (ex instanceof MissingDataException) {\n        throw ex;\n      }\n      warn(\"Unable to read page labels.\");\n    }\n    return shadow(this, \"pageLabels\", obj);\n  }\n  _readPageLabels() {\n    const obj = this._catDict.getRaw(\"PageLabels\");\n    if (!obj) {\n      return null;\n    }\n    const pageLabels = new Array(this.numPages);\n    let style = null,\n      prefix = \"\";\n    const numberTree = new NumberTree(obj, this.xref);\n    const nums = numberTree.getAll();\n    let currentLabel = \"\",\n      currentIndex = 1;\n    for (let i = 0, ii = this.numPages; i < ii; i++) {\n      const labelDict = nums.get(i);\n      if (labelDict !== undefined) {\n        if (!(labelDict instanceof Dict)) {\n          throw new FormatError(\"PageLabel is not a dictionary.\");\n        }\n        if (labelDict.has(\"Type\") && !isName(labelDict.get(\"Type\"), \"PageLabel\")) {\n          throw new FormatError(\"Invalid type in PageLabel dictionary.\");\n        }\n        if (labelDict.has(\"S\")) {\n          const s = labelDict.get(\"S\");\n          if (!(s instanceof Name)) {\n            throw new FormatError(\"Invalid style in PageLabel dictionary.\");\n          }\n          style = s.name;\n        } else {\n          style = null;\n        }\n        if (labelDict.has(\"P\")) {\n          const p = labelDict.get(\"P\");\n          if (typeof p !== \"string\") {\n            throw new FormatError(\"Invalid prefix in PageLabel dictionary.\");\n          }\n          prefix = stringToPDFString(p);\n        } else {\n          prefix = \"\";\n        }\n        if (labelDict.has(\"St\")) {\n          const st = labelDict.get(\"St\");\n          if (!(Number.isInteger(st) && st >= 1)) {\n            throw new FormatError(\"Invalid start in PageLabel dictionary.\");\n          }\n          currentIndex = st;\n        } else {\n          currentIndex = 1;\n        }\n      }\n      switch (style) {\n        case \"D\":\n          currentLabel = currentIndex;\n          break;\n        case \"R\":\n        case \"r\":\n          currentLabel = toRomanNumerals(currentIndex, style === \"r\");\n          break;\n        case \"A\":\n        case \"a\":\n          const LIMIT = 26;\n          const A_UPPER_CASE = 0x41,\n            A_LOWER_CASE = 0x61;\n          const baseCharCode = style === \"a\" ? A_LOWER_CASE : A_UPPER_CASE;\n          const letterIndex = currentIndex - 1;\n          const character = String.fromCharCode(baseCharCode + letterIndex % LIMIT);\n          currentLabel = character.repeat(Math.floor(letterIndex / LIMIT) + 1);\n          break;\n        default:\n          if (style) {\n            throw new FormatError(`Invalid style \"${style}\" in PageLabel dictionary.`);\n          }\n          currentLabel = \"\";\n      }\n      pageLabels[i] = prefix + currentLabel;\n      currentIndex++;\n    }\n    return pageLabels;\n  }\n  get pageLayout() {\n    const obj = this._catDict.get(\"PageLayout\");\n    let pageLayout = \"\";\n    if (obj instanceof Name) {\n      switch (obj.name) {\n        case \"SinglePage\":\n        case \"OneColumn\":\n        case \"TwoColumnLeft\":\n        case \"TwoColumnRight\":\n        case \"TwoPageLeft\":\n        case \"TwoPageRight\":\n          pageLayout = obj.name;\n      }\n    }\n    return shadow(this, \"pageLayout\", pageLayout);\n  }\n  get pageMode() {\n    const obj = this._catDict.get(\"PageMode\");\n    let pageMode = \"UseNone\";\n    if (obj instanceof Name) {\n      switch (obj.name) {\n        case \"UseNone\":\n        case \"UseOutlines\":\n        case \"UseThumbs\":\n        case \"FullScreen\":\n        case \"UseOC\":\n        case \"UseAttachments\":\n          pageMode = obj.name;\n      }\n    }\n    return shadow(this, \"pageMode\", pageMode);\n  }\n  get viewerPreferences() {\n    const obj = this._catDict.get(\"ViewerPreferences\");\n    if (!(obj instanceof Dict)) {\n      return shadow(this, \"viewerPreferences\", null);\n    }\n    let prefs = null;\n    for (const key of obj.getKeys()) {\n      const value = obj.get(key);\n      let prefValue;\n      switch (key) {\n        case \"HideToolbar\":\n        case \"HideMenubar\":\n        case \"HideWindowUI\":\n        case \"FitWindow\":\n        case \"CenterWindow\":\n        case \"DisplayDocTitle\":\n        case \"PickTrayByPDFSize\":\n          if (typeof value === \"boolean\") {\n            prefValue = value;\n          }\n          break;\n        case \"NonFullScreenPageMode\":\n          if (value instanceof Name) {\n            switch (value.name) {\n              case \"UseNone\":\n              case \"UseOutlines\":\n              case \"UseThumbs\":\n              case \"UseOC\":\n                prefValue = value.name;\n                break;\n              default:\n                prefValue = \"UseNone\";\n            }\n          }\n          break;\n        case \"Direction\":\n          if (value instanceof Name) {\n            switch (value.name) {\n              case \"L2R\":\n              case \"R2L\":\n                prefValue = value.name;\n                break;\n              default:\n                prefValue = \"L2R\";\n            }\n          }\n          break;\n        case \"ViewArea\":\n        case \"ViewClip\":\n        case \"PrintArea\":\n        case \"PrintClip\":\n          if (value instanceof Name) {\n            switch (value.name) {\n              case \"MediaBox\":\n              case \"CropBox\":\n              case \"BleedBox\":\n              case \"TrimBox\":\n              case \"ArtBox\":\n                prefValue = value.name;\n                break;\n              default:\n                prefValue = \"CropBox\";\n            }\n          }\n          break;\n        case \"PrintScaling\":\n          if (value instanceof Name) {\n            switch (value.name) {\n              case \"None\":\n              case \"AppDefault\":\n                prefValue = value.name;\n                break;\n              default:\n                prefValue = \"AppDefault\";\n            }\n          }\n          break;\n        case \"Duplex\":\n          if (value instanceof Name) {\n            switch (value.name) {\n              case \"Simplex\":\n              case \"DuplexFlipShortEdge\":\n              case \"DuplexFlipLongEdge\":\n                prefValue = value.name;\n                break;\n              default:\n                prefValue = \"None\";\n            }\n          }\n          break;\n        case \"PrintPageRange\":\n          if (Array.isArray(value) && value.length % 2 === 0) {\n            const isValid = value.every((page, i, arr) => Number.isInteger(page) && page > 0 && (i === 0 || page >= arr[i - 1]) && page <= this.numPages);\n            if (isValid) {\n              prefValue = value;\n            }\n          }\n          break;\n        case \"NumCopies\":\n          if (Number.isInteger(value) && value > 0) {\n            prefValue = value;\n          }\n          break;\n        default:\n          warn(`Ignoring non-standard key in ViewerPreferences: ${key}.`);\n          continue;\n      }\n      if (prefValue === undefined) {\n        warn(`Bad value, for key \"${key}\", in ViewerPreferences: ${value}.`);\n        continue;\n      }\n      if (!prefs) {\n        prefs = Object.create(null);\n      }\n      prefs[key] = prefValue;\n    }\n    return shadow(this, \"viewerPreferences\", prefs);\n  }\n  get openAction() {\n    const obj = this._catDict.get(\"OpenAction\");\n    const openAction = Object.create(null);\n    if (obj instanceof Dict) {\n      const destDict = new Dict(this.xref);\n      destDict.set(\"A\", obj);\n      const resultObj = {\n        url: null,\n        dest: null,\n        action: null\n      };\n      Catalog.parseDestDictionary({\n        destDict,\n        resultObj\n      });\n      if (Array.isArray(resultObj.dest)) {\n        openAction.dest = resultObj.dest;\n      } else if (resultObj.action) {\n        openAction.action = resultObj.action;\n      }\n    } else if (Array.isArray(obj)) {\n      openAction.dest = obj;\n    }\n    return shadow(this, \"openAction\", objectSize(openAction) > 0 ? openAction : null);\n  }\n  get attachments() {\n    const obj = this._catDict.get(\"Names\");\n    let attachments = null;\n    if (obj instanceof Dict && obj.has(\"EmbeddedFiles\")) {\n      const nameTree = new NameTree(obj.getRaw(\"EmbeddedFiles\"), this.xref);\n      for (const [key, value] of nameTree.getAll()) {\n        const fs = new FileSpec(value, this.xref);\n        if (!attachments) {\n          attachments = Object.create(null);\n        }\n        attachments[stringToPDFString(key)] = fs.serializable;\n      }\n    }\n    return shadow(this, \"attachments\", attachments);\n  }\n  get xfaImages() {\n    const obj = this._catDict.get(\"Names\");\n    let xfaImages = null;\n    if (obj instanceof Dict && obj.has(\"XFAImages\")) {\n      const nameTree = new NameTree(obj.getRaw(\"XFAImages\"), this.xref);\n      for (const [key, value] of nameTree.getAll()) {\n        if (!xfaImages) {\n          xfaImages = new Dict(this.xref);\n        }\n        xfaImages.set(stringToPDFString(key), value);\n      }\n    }\n    return shadow(this, \"xfaImages\", xfaImages);\n  }\n  _collectJavaScript() {\n    const obj = this._catDict.get(\"Names\");\n    let javaScript = null;\n    function appendIfJavaScriptDict(name, jsDict) {\n      if (!(jsDict instanceof Dict)) {\n        return;\n      }\n      if (!isName(jsDict.get(\"S\"), \"JavaScript\")) {\n        return;\n      }\n      let js = jsDict.get(\"JS\");\n      if (js instanceof BaseStream) {\n        js = js.getString();\n      } else if (typeof js !== \"string\") {\n        return;\n      }\n      js = stringToPDFString(js).replaceAll(\"\\x00\", \"\");\n      if (js) {\n        (javaScript ||= new Map()).set(name, js);\n      }\n    }\n    if (obj instanceof Dict && obj.has(\"JavaScript\")) {\n      const nameTree = new NameTree(obj.getRaw(\"JavaScript\"), this.xref);\n      for (const [key, value] of nameTree.getAll()) {\n        appendIfJavaScriptDict(stringToPDFString(key), value);\n      }\n    }\n    const openAction = this._catDict.get(\"OpenAction\");\n    if (openAction) {\n      appendIfJavaScriptDict(\"OpenAction\", openAction);\n    }\n    return javaScript;\n  }\n  get jsActions() {\n    const javaScript = this._collectJavaScript();\n    let actions = collectActions(this.xref, this._catDict, DocumentActionEventType);\n    if (javaScript) {\n      actions ||= Object.create(null);\n      for (const [key, val] of javaScript) {\n        if (key in actions) {\n          actions[key].push(val);\n        } else {\n          actions[key] = [val];\n        }\n      }\n    }\n    return shadow(this, \"jsActions\", actions);\n  }\n  async fontFallback(id, handler) {\n    const translatedFonts = await Promise.all(this.fontCache);\n    for (const translatedFont of translatedFonts) {\n      if (translatedFont.loadedName === id) {\n        translatedFont.fallback(handler);\n        return;\n      }\n    }\n  }\n  async cleanup(manuallyTriggered = false) {\n    clearGlobalCaches();\n    this.globalImageCache.clear(manuallyTriggered);\n    this.pageKidsCountCache.clear();\n    this.pageIndexCache.clear();\n    this.nonBlendModesSet.clear();\n    const translatedFonts = await Promise.all(this.fontCache);\n    for (const {\n      dict\n    } of translatedFonts) {\n      delete dict.cacheKey;\n    }\n    this.fontCache.clear();\n    this.builtInCMapCache.clear();\n    this.standardFontDataCache.clear();\n    this.systemFontCache.clear();\n  }\n  async getPageDict(pageIndex) {\n    const nodesToVisit = [this.toplevelPagesDict];\n    const visitedNodes = new RefSet();\n    const pagesRef = this._catDict.getRaw(\"Pages\");\n    if (pagesRef instanceof Ref) {\n      visitedNodes.put(pagesRef);\n    }\n    const xref = this.xref,\n      pageKidsCountCache = this.pageKidsCountCache,\n      pageIndexCache = this.pageIndexCache;\n    let currentPageIndex = 0;\n    while (nodesToVisit.length) {\n      const currentNode = nodesToVisit.pop();\n      if (currentNode instanceof Ref) {\n        const count = pageKidsCountCache.get(currentNode);\n        if (count >= 0 && currentPageIndex + count <= pageIndex) {\n          currentPageIndex += count;\n          continue;\n        }\n        if (visitedNodes.has(currentNode)) {\n          throw new FormatError(\"Pages tree contains circular reference.\");\n        }\n        visitedNodes.put(currentNode);\n        const obj = await xref.fetchAsync(currentNode);\n        if (obj instanceof Dict) {\n          let type = obj.getRaw(\"Type\");\n          if (type instanceof Ref) {\n            type = await xref.fetchAsync(type);\n          }\n          if (isName(type, \"Page\") || !obj.has(\"Kids\")) {\n            if (!pageKidsCountCache.has(currentNode)) {\n              pageKidsCountCache.put(currentNode, 1);\n            }\n            if (!pageIndexCache.has(currentNode)) {\n              pageIndexCache.put(currentNode, currentPageIndex);\n            }\n            if (currentPageIndex === pageIndex) {\n              return [obj, currentNode];\n            }\n            currentPageIndex++;\n            continue;\n          }\n        }\n        nodesToVisit.push(obj);\n        continue;\n      }\n      if (!(currentNode instanceof Dict)) {\n        throw new FormatError(\"Page dictionary kid reference points to wrong type of object.\");\n      }\n      const {\n        objId\n      } = currentNode;\n      let count = currentNode.getRaw(\"Count\");\n      if (count instanceof Ref) {\n        count = await xref.fetchAsync(count);\n      }\n      if (Number.isInteger(count) && count >= 0) {\n        if (objId && !pageKidsCountCache.has(objId)) {\n          pageKidsCountCache.put(objId, count);\n        }\n        if (currentPageIndex + count <= pageIndex) {\n          currentPageIndex += count;\n          continue;\n        }\n      }\n      let kids = currentNode.getRaw(\"Kids\");\n      if (kids instanceof Ref) {\n        kids = await xref.fetchAsync(kids);\n      }\n      if (!Array.isArray(kids)) {\n        let type = currentNode.getRaw(\"Type\");\n        if (type instanceof Ref) {\n          type = await xref.fetchAsync(type);\n        }\n        if (isName(type, \"Page\") || !currentNode.has(\"Kids\")) {\n          if (currentPageIndex === pageIndex) {\n            return [currentNode, null];\n          }\n          currentPageIndex++;\n          continue;\n        }\n        throw new FormatError(\"Page dictionary kids object is not an array.\");\n      }\n      for (let last = kids.length - 1; last >= 0; last--) {\n        nodesToVisit.push(kids[last]);\n      }\n    }\n    throw new Error(`Page index ${pageIndex} not found.`);\n  }\n  async getAllPageDicts(recoveryMode = false) {\n    const {\n      ignoreErrors\n    } = this.pdfManager.evaluatorOptions;\n    const queue = [{\n      currentNode: this.toplevelPagesDict,\n      posInKids: 0\n    }];\n    const visitedNodes = new RefSet();\n    const pagesRef = this._catDict.getRaw(\"Pages\");\n    if (pagesRef instanceof Ref) {\n      visitedNodes.put(pagesRef);\n    }\n    const map = new Map(),\n      xref = this.xref,\n      pageIndexCache = this.pageIndexCache;\n    let pageIndex = 0;\n    function addPageDict(pageDict, pageRef) {\n      if (pageRef && !pageIndexCache.has(pageRef)) {\n        pageIndexCache.put(pageRef, pageIndex);\n      }\n      map.set(pageIndex++, [pageDict, pageRef]);\n    }\n    function addPageError(error) {\n      if (error instanceof XRefEntryException && !recoveryMode) {\n        throw error;\n      }\n      if (recoveryMode && ignoreErrors && pageIndex === 0) {\n        warn(`getAllPageDicts - Skipping invalid first page: \"${error}\".`);\n        error = Dict.empty;\n      }\n      map.set(pageIndex++, [error, null]);\n    }\n    while (queue.length > 0) {\n      const queueItem = queue.at(-1);\n      const {\n        currentNode,\n        posInKids\n      } = queueItem;\n      let kids = currentNode.getRaw(\"Kids\");\n      if (kids instanceof Ref) {\n        try {\n          kids = await xref.fetchAsync(kids);\n        } catch (ex) {\n          addPageError(ex);\n          break;\n        }\n      }\n      if (!Array.isArray(kids)) {\n        addPageError(new FormatError(\"Page dictionary kids object is not an array.\"));\n        break;\n      }\n      if (posInKids >= kids.length) {\n        queue.pop();\n        continue;\n      }\n      const kidObj = kids[posInKids];\n      let obj;\n      if (kidObj instanceof Ref) {\n        if (visitedNodes.has(kidObj)) {\n          addPageError(new FormatError(\"Pages tree contains circular reference.\"));\n          break;\n        }\n        visitedNodes.put(kidObj);\n        try {\n          obj = await xref.fetchAsync(kidObj);\n        } catch (ex) {\n          addPageError(ex);\n          break;\n        }\n      } else {\n        obj = kidObj;\n      }\n      if (!(obj instanceof Dict)) {\n        addPageError(new FormatError(\"Page dictionary kid reference points to wrong type of object.\"));\n        break;\n      }\n      let type = obj.getRaw(\"Type\");\n      if (type instanceof Ref) {\n        try {\n          type = await xref.fetchAsync(type);\n        } catch (ex) {\n          addPageError(ex);\n          break;\n        }\n      }\n      if (isName(type, \"Page\") || !obj.has(\"Kids\")) {\n        addPageDict(obj, kidObj instanceof Ref ? kidObj : null);\n      } else {\n        queue.push({\n          currentNode: obj,\n          posInKids: 0\n        });\n      }\n      queueItem.posInKids++;\n    }\n    return map;\n  }\n  getPageIndex(pageRef) {\n    const cachedPageIndex = this.pageIndexCache.get(pageRef);\n    if (cachedPageIndex !== undefined) {\n      return Promise.resolve(cachedPageIndex);\n    }\n    const xref = this.xref;\n    function pagesBeforeRef(kidRef) {\n      let total = 0,\n        parentRef;\n      return xref.fetchAsync(kidRef).then(function (node) {\n        if (isRefsEqual(kidRef, pageRef) && !isDict(node, \"Page\") && !(node instanceof Dict && !node.has(\"Type\") && node.has(\"Contents\"))) {\n          throw new FormatError(\"The reference does not point to a /Page dictionary.\");\n        }\n        if (!node) {\n          return null;\n        }\n        if (!(node instanceof Dict)) {\n          throw new FormatError(\"Node must be a dictionary.\");\n        }\n        parentRef = node.getRaw(\"Parent\");\n        return node.getAsync(\"Parent\");\n      }).then(function (parent) {\n        if (!parent) {\n          return null;\n        }\n        if (!(parent instanceof Dict)) {\n          throw new FormatError(\"Parent must be a dictionary.\");\n        }\n        return parent.getAsync(\"Kids\");\n      }).then(function (kids) {\n        if (!kids) {\n          return null;\n        }\n        const kidPromises = [];\n        let found = false;\n        for (const kid of kids) {\n          if (!(kid instanceof Ref)) {\n            throw new FormatError(\"Kid must be a reference.\");\n          }\n          if (isRefsEqual(kid, kidRef)) {\n            found = true;\n            break;\n          }\n          kidPromises.push(xref.fetchAsync(kid).then(function (obj) {\n            if (!(obj instanceof Dict)) {\n              throw new FormatError(\"Kid node must be a dictionary.\");\n            }\n            if (obj.has(\"Count\")) {\n              total += obj.get(\"Count\");\n            } else {\n              total++;\n            }\n          }));\n        }\n        if (!found) {\n          throw new FormatError(\"Kid reference not found in parent's kids.\");\n        }\n        return Promise.all(kidPromises).then(function () {\n          return [total, parentRef];\n        });\n      });\n    }\n    let total = 0;\n    const next = ref => pagesBeforeRef(ref).then(args => {\n      if (!args) {\n        this.pageIndexCache.put(pageRef, total);\n        return total;\n      }\n      const [count, parentRef] = args;\n      total += count;\n      return next(parentRef);\n    });\n    return next(pageRef);\n  }\n  get baseUrl() {\n    const uri = this._catDict.get(\"URI\");\n    if (uri instanceof Dict) {\n      const base = uri.get(\"Base\");\n      if (typeof base === \"string\") {\n        const absoluteUrl = createValidAbsoluteUrl(base, null, {\n          tryConvertEncoding: true\n        });\n        if (absoluteUrl) {\n          return shadow(this, \"baseUrl\", absoluteUrl.href);\n        }\n      }\n    }\n    return shadow(this, \"baseUrl\", this.pdfManager.docBaseUrl);\n  }\n  static parseDestDictionary({\n    destDict,\n    resultObj,\n    docBaseUrl = null,\n    docAttachments = null\n  }) {\n    if (!(destDict instanceof Dict)) {\n      warn(\"parseDestDictionary: `destDict` must be a dictionary.\");\n      return;\n    }\n    let action = destDict.get(\"A\"),\n      url,\n      dest;\n    if (!(action instanceof Dict)) {\n      if (destDict.has(\"Dest\")) {\n        action = destDict.get(\"Dest\");\n      } else {\n        action = destDict.get(\"AA\");\n        if (action instanceof Dict) {\n          if (action.has(\"D\")) {\n            action = action.get(\"D\");\n          } else if (action.has(\"U\")) {\n            action = action.get(\"U\");\n          }\n        }\n      }\n    }\n    if (action instanceof Dict) {\n      const actionType = action.get(\"S\");\n      if (!(actionType instanceof Name)) {\n        warn(\"parseDestDictionary: Invalid type in Action dictionary.\");\n        return;\n      }\n      const actionName = actionType.name;\n      switch (actionName) {\n        case \"ResetForm\":\n          const flags = action.get(\"Flags\");\n          const include = ((typeof flags === \"number\" ? flags : 0) & 1) === 0;\n          const fields = [];\n          const refs = [];\n          for (const obj of action.get(\"Fields\") || []) {\n            if (obj instanceof Ref) {\n              refs.push(obj.toString());\n            } else if (typeof obj === \"string\") {\n              fields.push(stringToPDFString(obj));\n            }\n          }\n          resultObj.resetForm = {\n            fields,\n            refs,\n            include\n          };\n          break;\n        case \"URI\":\n          url = action.get(\"URI\");\n          if (url instanceof Name) {\n            url = \"/\" + url.name;\n          }\n          break;\n        case \"GoTo\":\n          dest = action.get(\"D\");\n          break;\n        case \"Launch\":\n        case \"GoToR\":\n          const urlDict = action.get(\"F\");\n          if (urlDict instanceof Dict) {\n            url = urlDict.get(\"F\") || null;\n          } else if (typeof urlDict === \"string\") {\n            url = urlDict;\n          }\n          const remoteDest = fetchRemoteDest(action);\n          if (remoteDest && typeof url === \"string\") {\n            url = url.split(\"#\", 1)[0] + \"#\" + remoteDest;\n          }\n          const newWindow = action.get(\"NewWindow\");\n          if (typeof newWindow === \"boolean\") {\n            resultObj.newWindow = newWindow;\n          }\n          break;\n        case \"GoToE\":\n          const target = action.get(\"T\");\n          let attachment;\n          if (docAttachments && target instanceof Dict) {\n            const relationship = target.get(\"R\");\n            const name = target.get(\"N\");\n            if (isName(relationship, \"C\") && typeof name === \"string\") {\n              attachment = docAttachments[stringToPDFString(name)];\n            }\n          }\n          if (attachment) {\n            resultObj.attachment = attachment;\n            const attachmentDest = fetchRemoteDest(action);\n            if (attachmentDest) {\n              resultObj.attachmentDest = attachmentDest;\n            }\n          } else {\n            warn(`parseDestDictionary - unimplemented \"GoToE\" action.`);\n          }\n          break;\n        case \"Named\":\n          const namedAction = action.get(\"N\");\n          if (namedAction instanceof Name) {\n            resultObj.action = namedAction.name;\n          }\n          break;\n        case \"SetOCGState\":\n          const state = action.get(\"State\");\n          const preserveRB = action.get(\"PreserveRB\");\n          if (!Array.isArray(state) || state.length === 0) {\n            break;\n          }\n          const stateArr = [];\n          for (const elem of state) {\n            if (elem instanceof Name) {\n              switch (elem.name) {\n                case \"ON\":\n                case \"OFF\":\n                case \"Toggle\":\n                  stateArr.push(elem.name);\n                  break;\n              }\n            } else if (elem instanceof Ref) {\n              stateArr.push(elem.toString());\n            }\n          }\n          if (stateArr.length !== state.length) {\n            break;\n          }\n          resultObj.setOCGState = {\n            state: stateArr,\n            preserveRB: typeof preserveRB === \"boolean\" ? preserveRB : true\n          };\n          break;\n        case \"JavaScript\":\n          const jsAction = action.get(\"JS\");\n          let js;\n          if (jsAction instanceof BaseStream) {\n            js = jsAction.getString();\n          } else if (typeof jsAction === \"string\") {\n            js = jsAction;\n          }\n          const jsURL = js && recoverJsURL(stringToPDFString(js));\n          if (jsURL) {\n            url = jsURL.url;\n            resultObj.newWindow = jsURL.newWindow;\n            break;\n          }\n        default:\n          if (actionName === \"JavaScript\" || actionName === \"SubmitForm\") {\n            break;\n          }\n          warn(`parseDestDictionary - unsupported action: \"${actionName}\".`);\n          break;\n      }\n    } else if (destDict.has(\"Dest\")) {\n      dest = destDict.get(\"Dest\");\n    }\n    if (typeof url === \"string\") {\n      const absoluteUrl = createValidAbsoluteUrl(url, docBaseUrl, {\n        addDefaultProtocol: true,\n        tryConvertEncoding: true\n      });\n      if (absoluteUrl) {\n        resultObj.url = absoluteUrl.href;\n      }\n      resultObj.unsafeUrl = url;\n    }\n    if (dest) {\n      if (dest instanceof Name) {\n        dest = dest.name;\n      }\n      if (typeof dest === \"string\") {\n        resultObj.dest = stringToPDFString(dest);\n      } else if (Array.isArray(dest)) {\n        resultObj.dest = dest;\n      }\n    }\n  }\n}\n\n;// ./src/core/object_loader.js\n\n\n\n\nfunction mayHaveChildren(value) {\n  return value instanceof Ref || value instanceof Dict || value instanceof BaseStream || Array.isArray(value);\n}\nfunction addChildren(node, nodesToVisit) {\n  if (node instanceof Dict) {\n    node = node.getRawValues();\n  } else if (node instanceof BaseStream) {\n    node = node.dict.getRawValues();\n  } else if (!Array.isArray(node)) {\n    return;\n  }\n  for (const rawValue of node) {\n    if (mayHaveChildren(rawValue)) {\n      nodesToVisit.push(rawValue);\n    }\n  }\n}\nclass ObjectLoader {\n  constructor(dict, keys, xref) {\n    this.dict = dict;\n    this.keys = keys;\n    this.xref = xref;\n    this.refSet = null;\n  }\n  async load() {\n    if (this.xref.stream.isDataLoaded) {\n      return undefined;\n    }\n    const {\n      keys,\n      dict\n    } = this;\n    this.refSet = new RefSet();\n    const nodesToVisit = [];\n    for (const key of keys) {\n      const rawValue = dict.getRaw(key);\n      if (rawValue !== undefined) {\n        nodesToVisit.push(rawValue);\n      }\n    }\n    return this._walk(nodesToVisit);\n  }\n  async _walk(nodesToVisit) {\n    const nodesToRevisit = [];\n    const pendingRequests = [];\n    while (nodesToVisit.length) {\n      let currentNode = nodesToVisit.pop();\n      if (currentNode instanceof Ref) {\n        if (this.refSet.has(currentNode)) {\n          continue;\n        }\n        try {\n          this.refSet.put(currentNode);\n          currentNode = this.xref.fetch(currentNode);\n        } catch (ex) {\n          if (!(ex instanceof MissingDataException)) {\n            warn(`ObjectLoader._walk - requesting all data: \"${ex}\".`);\n            this.refSet = null;\n            const {\n              manager\n            } = this.xref.stream;\n            return manager.requestAllChunks();\n          }\n          nodesToRevisit.push(currentNode);\n          pendingRequests.push({\n            begin: ex.begin,\n            end: ex.end\n          });\n        }\n      }\n      if (currentNode instanceof BaseStream) {\n        const baseStreams = currentNode.getBaseStreams();\n        if (baseStreams) {\n          let foundMissingData = false;\n          for (const stream of baseStreams) {\n            if (stream.isDataLoaded) {\n              continue;\n            }\n            foundMissingData = true;\n            pendingRequests.push({\n              begin: stream.start,\n              end: stream.end\n            });\n          }\n          if (foundMissingData) {\n            nodesToRevisit.push(currentNode);\n          }\n        }\n      }\n      addChildren(currentNode, nodesToVisit);\n    }\n    if (pendingRequests.length) {\n      await this.xref.stream.manager.requestRanges(pendingRequests);\n      for (const node of nodesToRevisit) {\n        if (node instanceof Ref) {\n          this.refSet.remove(node);\n        }\n      }\n      return this._walk(nodesToRevisit);\n    }\n    this.refSet = null;\n    return undefined;\n  }\n}\n\n;// ./src/core/xfa/symbol_utils.js\nconst $acceptWhitespace = Symbol();\nconst $addHTML = Symbol();\nconst $appendChild = Symbol();\nconst $childrenToHTML = Symbol();\nconst $clean = Symbol();\nconst $cleanPage = Symbol();\nconst $cleanup = Symbol();\nconst $clone = Symbol();\nconst $consumed = Symbol();\nconst $content = Symbol(\"content\");\nconst $data = Symbol(\"data\");\nconst $dump = Symbol();\nconst $extra = Symbol(\"extra\");\nconst $finalize = Symbol();\nconst $flushHTML = Symbol();\nconst $getAttributeIt = Symbol();\nconst $getAttributes = Symbol();\nconst $getAvailableSpace = Symbol();\nconst $getChildrenByClass = Symbol();\nconst $getChildrenByName = Symbol();\nconst $getChildrenByNameIt = Symbol();\nconst $getDataValue = Symbol();\nconst $getExtra = Symbol();\nconst $getRealChildrenByNameIt = Symbol();\nconst $getChildren = Symbol();\nconst $getContainedChildren = Symbol();\nconst $getNextPage = Symbol();\nconst $getSubformParent = Symbol();\nconst $getParent = Symbol();\nconst $getTemplateRoot = Symbol();\nconst $globalData = Symbol();\nconst $hasSettableValue = Symbol();\nconst $ids = Symbol();\nconst $indexOf = Symbol();\nconst $insertAt = Symbol();\nconst $isCDATAXml = Symbol();\nconst $isBindable = Symbol();\nconst $isDataValue = Symbol();\nconst $isDescendent = Symbol();\nconst $isNsAgnostic = Symbol();\nconst $isSplittable = Symbol();\nconst $isThereMoreWidth = Symbol();\nconst $isTransparent = Symbol();\nconst $isUsable = Symbol();\nconst $lastAttribute = Symbol();\nconst $namespaceId = Symbol(\"namespaceId\");\nconst $nodeName = Symbol(\"nodeName\");\nconst $nsAttributes = Symbol();\nconst $onChild = Symbol();\nconst $onChildCheck = Symbol();\nconst $onText = Symbol();\nconst $pushGlyphs = Symbol();\nconst $popPara = Symbol();\nconst $pushPara = Symbol();\nconst $removeChild = Symbol();\nconst $root = Symbol(\"root\");\nconst $resolvePrototypes = Symbol();\nconst $searchNode = Symbol();\nconst $setId = Symbol();\nconst $setSetAttributes = Symbol();\nconst $setValue = Symbol();\nconst $tabIndex = Symbol();\nconst $text = Symbol();\nconst $toPages = Symbol();\nconst $toHTML = Symbol();\nconst $toString = Symbol();\nconst $toStyle = Symbol();\nconst $uid = Symbol(\"uid\");\n\n;// ./src/core/xfa/namespaces.js\nconst $buildXFAObject = Symbol();\nconst NamespaceIds = {\n  config: {\n    id: 0,\n    check: ns => ns.startsWith(\"http://www.xfa.org/schema/xci/\")\n  },\n  connectionSet: {\n    id: 1,\n    check: ns => ns.startsWith(\"http://www.xfa.org/schema/xfa-connection-set/\")\n  },\n  datasets: {\n    id: 2,\n    check: ns => ns.startsWith(\"http://www.xfa.org/schema/xfa-data/\")\n  },\n  form: {\n    id: 3,\n    check: ns => ns.startsWith(\"http://www.xfa.org/schema/xfa-form/\")\n  },\n  localeSet: {\n    id: 4,\n    check: ns => ns.startsWith(\"http://www.xfa.org/schema/xfa-locale-set/\")\n  },\n  pdf: {\n    id: 5,\n    check: ns => ns === \"http://ns.adobe.com/xdp/pdf/\"\n  },\n  signature: {\n    id: 6,\n    check: ns => ns === \"http://www.w3.org/2000/09/xmldsig#\"\n  },\n  sourceSet: {\n    id: 7,\n    check: ns => ns.startsWith(\"http://www.xfa.org/schema/xfa-source-set/\")\n  },\n  stylesheet: {\n    id: 8,\n    check: ns => ns === \"http://www.w3.org/1999/XSL/Transform\"\n  },\n  template: {\n    id: 9,\n    check: ns => ns.startsWith(\"http://www.xfa.org/schema/xfa-template/\")\n  },\n  xdc: {\n    id: 10,\n    check: ns => ns.startsWith(\"http://www.xfa.org/schema/xdc/\")\n  },\n  xdp: {\n    id: 11,\n    check: ns => ns === \"http://ns.adobe.com/xdp/\"\n  },\n  xfdf: {\n    id: 12,\n    check: ns => ns === \"http://ns.adobe.com/xfdf/\"\n  },\n  xhtml: {\n    id: 13,\n    check: ns => ns === \"http://www.w3.org/1999/xhtml\"\n  },\n  xmpmeta: {\n    id: 14,\n    check: ns => ns === \"http://ns.adobe.com/xmpmeta/\"\n  }\n};\n\n;// ./src/core/xfa/utils.js\n\nconst dimConverters = {\n  pt: x => x,\n  cm: x => x / 2.54 * 72,\n  mm: x => x / (10 * 2.54) * 72,\n  in: x => x * 72,\n  px: x => x\n};\nconst measurementPattern = /([+-]?\\d+\\.?\\d*)(.*)/;\nfunction stripQuotes(str) {\n  if (str.startsWith(\"'\") || str.startsWith('\"')) {\n    return str.slice(1, -1);\n  }\n  return str;\n}\nfunction getInteger({\n  data,\n  defaultValue,\n  validate\n}) {\n  if (!data) {\n    return defaultValue;\n  }\n  data = data.trim();\n  const n = parseInt(data, 10);\n  if (!isNaN(n) && validate(n)) {\n    return n;\n  }\n  return defaultValue;\n}\nfunction getFloat({\n  data,\n  defaultValue,\n  validate\n}) {\n  if (!data) {\n    return defaultValue;\n  }\n  data = data.trim();\n  const n = parseFloat(data);\n  if (!isNaN(n) && validate(n)) {\n    return n;\n  }\n  return defaultValue;\n}\nfunction getKeyword({\n  data,\n  defaultValue,\n  validate\n}) {\n  if (!data) {\n    return defaultValue;\n  }\n  data = data.trim();\n  if (validate(data)) {\n    return data;\n  }\n  return defaultValue;\n}\nfunction getStringOption(data, options) {\n  return getKeyword({\n    data,\n    defaultValue: options[0],\n    validate: k => options.includes(k)\n  });\n}\nfunction getMeasurement(str, def = \"0\") {\n  def ||= \"0\";\n  if (!str) {\n    return getMeasurement(def);\n  }\n  const match = str.trim().match(measurementPattern);\n  if (!match) {\n    return getMeasurement(def);\n  }\n  const [, valueStr, unit] = match;\n  const value = parseFloat(valueStr);\n  if (isNaN(value)) {\n    return getMeasurement(def);\n  }\n  if (value === 0) {\n    return 0;\n  }\n  const conv = dimConverters[unit];\n  if (conv) {\n    return conv(value);\n  }\n  return value;\n}\nfunction getRatio(data) {\n  if (!data) {\n    return {\n      num: 1,\n      den: 1\n    };\n  }\n  const ratio = data.trim().split(/\\s*:\\s*/).map(x => parseFloat(x)).filter(x => !isNaN(x));\n  if (ratio.length === 1) {\n    ratio.push(1);\n  }\n  if (ratio.length === 0) {\n    return {\n      num: 1,\n      den: 1\n    };\n  }\n  const [num, den] = ratio;\n  return {\n    num,\n    den\n  };\n}\nfunction getRelevant(data) {\n  if (!data) {\n    return [];\n  }\n  return data.trim().split(/\\s+/).map(e => ({\n    excluded: e[0] === \"-\",\n    viewname: e.substring(1)\n  }));\n}\nfunction getColor(data, def = [0, 0, 0]) {\n  let [r, g, b] = def;\n  if (!data) {\n    return {\n      r,\n      g,\n      b\n    };\n  }\n  const color = data.trim().split(/\\s*,\\s*/).map(c => Math.min(Math.max(0, parseInt(c.trim(), 10)), 255)).map(c => isNaN(c) ? 0 : c);\n  if (color.length < 3) {\n    return {\n      r,\n      g,\n      b\n    };\n  }\n  [r, g, b] = color;\n  return {\n    r,\n    g,\n    b\n  };\n}\nfunction getBBox(data) {\n  const def = -1;\n  if (!data) {\n    return {\n      x: def,\n      y: def,\n      width: def,\n      height: def\n    };\n  }\n  const bbox = data.trim().split(/\\s*,\\s*/).map(m => getMeasurement(m, \"-1\"));\n  if (bbox.length < 4 || bbox[2] < 0 || bbox[3] < 0) {\n    return {\n      x: def,\n      y: def,\n      width: def,\n      height: def\n    };\n  }\n  const [x, y, width, height] = bbox;\n  return {\n    x,\n    y,\n    width,\n    height\n  };\n}\nclass HTMLResult {\n  static get FAILURE() {\n    return shadow(this, \"FAILURE\", new HTMLResult(false, null, null, null));\n  }\n  static get EMPTY() {\n    return shadow(this, \"EMPTY\", new HTMLResult(true, null, null, null));\n  }\n  constructor(success, html, bbox, breakNode) {\n    this.success = success;\n    this.html = html;\n    this.bbox = bbox;\n    this.breakNode = breakNode;\n  }\n  isBreak() {\n    return !!this.breakNode;\n  }\n  static breakNode(node) {\n    return new HTMLResult(false, null, null, node);\n  }\n  static success(html, bbox = null) {\n    return new HTMLResult(true, html, bbox, null);\n  }\n}\n\n;// ./src/core/xfa/fonts.js\n\n\n\nclass FontFinder {\n  constructor(pdfFonts) {\n    this.fonts = new Map();\n    this.cache = new Map();\n    this.warned = new Set();\n    this.defaultFont = null;\n    this.add(pdfFonts);\n  }\n  add(pdfFonts, reallyMissingFonts = null) {\n    for (const pdfFont of pdfFonts) {\n      this.addPdfFont(pdfFont);\n    }\n    for (const pdfFont of this.fonts.values()) {\n      if (!pdfFont.regular) {\n        pdfFont.regular = pdfFont.italic || pdfFont.bold || pdfFont.bolditalic;\n      }\n    }\n    if (!reallyMissingFonts || reallyMissingFonts.size === 0) {\n      return;\n    }\n    const myriad = this.fonts.get(\"PdfJS-Fallback-PdfJS-XFA\");\n    for (const missing of reallyMissingFonts) {\n      this.fonts.set(missing, myriad);\n    }\n  }\n  addPdfFont(pdfFont) {\n    const cssFontInfo = pdfFont.cssFontInfo;\n    const name = cssFontInfo.fontFamily;\n    let font = this.fonts.get(name);\n    if (!font) {\n      font = Object.create(null);\n      this.fonts.set(name, font);\n      if (!this.defaultFont) {\n        this.defaultFont = font;\n      }\n    }\n    let property = \"\";\n    const fontWeight = parseFloat(cssFontInfo.fontWeight);\n    if (parseFloat(cssFontInfo.italicAngle) !== 0) {\n      property = fontWeight >= 700 ? \"bolditalic\" : \"italic\";\n    } else if (fontWeight >= 700) {\n      property = \"bold\";\n    }\n    if (!property) {\n      if (pdfFont.name.includes(\"Bold\") || pdfFont.psName?.includes(\"Bold\")) {\n        property = \"bold\";\n      }\n      if (pdfFont.name.includes(\"Italic\") || pdfFont.name.endsWith(\"It\") || pdfFont.psName?.includes(\"Italic\") || pdfFont.psName?.endsWith(\"It\")) {\n        property += \"italic\";\n      }\n    }\n    if (!property) {\n      property = \"regular\";\n    }\n    font[property] = pdfFont;\n  }\n  getDefault() {\n    return this.defaultFont;\n  }\n  find(fontName, mustWarn = true) {\n    let font = this.fonts.get(fontName) || this.cache.get(fontName);\n    if (font) {\n      return font;\n    }\n    const pattern = /,|-|_| |bolditalic|bold|italic|regular|it/gi;\n    let name = fontName.replaceAll(pattern, \"\");\n    font = this.fonts.get(name);\n    if (font) {\n      this.cache.set(fontName, font);\n      return font;\n    }\n    name = name.toLowerCase();\n    const maybe = [];\n    for (const [family, pdfFont] of this.fonts.entries()) {\n      if (family.replaceAll(pattern, \"\").toLowerCase().startsWith(name)) {\n        maybe.push(pdfFont);\n      }\n    }\n    if (maybe.length === 0) {\n      for (const [, pdfFont] of this.fonts.entries()) {\n        if (pdfFont.regular.name?.replaceAll(pattern, \"\").toLowerCase().startsWith(name)) {\n          maybe.push(pdfFont);\n        }\n      }\n    }\n    if (maybe.length === 0) {\n      name = name.replaceAll(/psmt|mt/gi, \"\");\n      for (const [family, pdfFont] of this.fonts.entries()) {\n        if (family.replaceAll(pattern, \"\").toLowerCase().startsWith(name)) {\n          maybe.push(pdfFont);\n        }\n      }\n    }\n    if (maybe.length === 0) {\n      for (const pdfFont of this.fonts.values()) {\n        if (pdfFont.regular.name?.replaceAll(pattern, \"\").toLowerCase().startsWith(name)) {\n          maybe.push(pdfFont);\n        }\n      }\n    }\n    if (maybe.length >= 1) {\n      if (maybe.length !== 1 && mustWarn) {\n        warn(`XFA - Too many choices to guess the correct font: ${fontName}`);\n      }\n      this.cache.set(fontName, maybe[0]);\n      return maybe[0];\n    }\n    if (mustWarn && !this.warned.has(fontName)) {\n      this.warned.add(fontName);\n      warn(`XFA - Cannot find the font: ${fontName}`);\n    }\n    return null;\n  }\n}\nfunction selectFont(xfaFont, typeface) {\n  if (xfaFont.posture === \"italic\") {\n    if (xfaFont.weight === \"bold\") {\n      return typeface.bolditalic;\n    }\n    return typeface.italic;\n  } else if (xfaFont.weight === \"bold\") {\n    return typeface.bold;\n  }\n  return typeface.regular;\n}\nfunction fonts_getMetrics(xfaFont, real = false) {\n  let pdfFont = null;\n  if (xfaFont) {\n    const name = stripQuotes(xfaFont.typeface);\n    const typeface = xfaFont[$globalData].fontFinder.find(name);\n    pdfFont = selectFont(xfaFont, typeface);\n  }\n  if (!pdfFont) {\n    return {\n      lineHeight: 12,\n      lineGap: 2,\n      lineNoGap: 10\n    };\n  }\n  const size = xfaFont.size || 10;\n  const lineHeight = pdfFont.lineHeight ? Math.max(real ? 0 : 1.2, pdfFont.lineHeight) : 1.2;\n  const lineGap = pdfFont.lineGap === undefined ? 0.2 : pdfFont.lineGap;\n  return {\n    lineHeight: lineHeight * size,\n    lineGap: lineGap * size,\n    lineNoGap: Math.max(1, lineHeight - lineGap) * size\n  };\n}\n\n;// ./src/core/xfa/text.js\n\nconst WIDTH_FACTOR = 1.02;\nclass FontInfo {\n  constructor(xfaFont, margin, lineHeight, fontFinder) {\n    this.lineHeight = lineHeight;\n    this.paraMargin = margin || {\n      top: 0,\n      bottom: 0,\n      left: 0,\n      right: 0\n    };\n    if (!xfaFont) {\n      [this.pdfFont, this.xfaFont] = this.defaultFont(fontFinder);\n      return;\n    }\n    this.xfaFont = {\n      typeface: xfaFont.typeface,\n      posture: xfaFont.posture,\n      weight: xfaFont.weight,\n      size: xfaFont.size,\n      letterSpacing: xfaFont.letterSpacing\n    };\n    const typeface = fontFinder.find(xfaFont.typeface);\n    if (!typeface) {\n      [this.pdfFont, this.xfaFont] = this.defaultFont(fontFinder);\n      return;\n    }\n    this.pdfFont = selectFont(xfaFont, typeface);\n    if (!this.pdfFont) {\n      [this.pdfFont, this.xfaFont] = this.defaultFont(fontFinder);\n    }\n  }\n  defaultFont(fontFinder) {\n    const font = fontFinder.find(\"Helvetica\", false) || fontFinder.find(\"Myriad Pro\", false) || fontFinder.find(\"Arial\", false) || fontFinder.getDefault();\n    if (font?.regular) {\n      const pdfFont = font.regular;\n      const info = pdfFont.cssFontInfo;\n      const xfaFont = {\n        typeface: info.fontFamily,\n        posture: \"normal\",\n        weight: \"normal\",\n        size: 10,\n        letterSpacing: 0\n      };\n      return [pdfFont, xfaFont];\n    }\n    const xfaFont = {\n      typeface: \"Courier\",\n      posture: \"normal\",\n      weight: \"normal\",\n      size: 10,\n      letterSpacing: 0\n    };\n    return [null, xfaFont];\n  }\n}\nclass FontSelector {\n  constructor(defaultXfaFont, defaultParaMargin, defaultLineHeight, fontFinder) {\n    this.fontFinder = fontFinder;\n    this.stack = [new FontInfo(defaultXfaFont, defaultParaMargin, defaultLineHeight, fontFinder)];\n  }\n  pushData(xfaFont, margin, lineHeight) {\n    const lastFont = this.stack.at(-1);\n    for (const name of [\"typeface\", \"posture\", \"weight\", \"size\", \"letterSpacing\"]) {\n      if (!xfaFont[name]) {\n        xfaFont[name] = lastFont.xfaFont[name];\n      }\n    }\n    for (const name of [\"top\", \"bottom\", \"left\", \"right\"]) {\n      if (isNaN(margin[name])) {\n        margin[name] = lastFont.paraMargin[name];\n      }\n    }\n    const fontInfo = new FontInfo(xfaFont, margin, lineHeight || lastFont.lineHeight, this.fontFinder);\n    if (!fontInfo.pdfFont) {\n      fontInfo.pdfFont = lastFont.pdfFont;\n    }\n    this.stack.push(fontInfo);\n  }\n  popFont() {\n    this.stack.pop();\n  }\n  topFont() {\n    return this.stack.at(-1);\n  }\n}\nclass TextMeasure {\n  constructor(defaultXfaFont, defaultParaMargin, defaultLineHeight, fonts) {\n    this.glyphs = [];\n    this.fontSelector = new FontSelector(defaultXfaFont, defaultParaMargin, defaultLineHeight, fonts);\n    this.extraHeight = 0;\n  }\n  pushData(xfaFont, margin, lineHeight) {\n    this.fontSelector.pushData(xfaFont, margin, lineHeight);\n  }\n  popFont(xfaFont) {\n    return this.fontSelector.popFont();\n  }\n  addPara() {\n    const lastFont = this.fontSelector.topFont();\n    this.extraHeight += lastFont.paraMargin.top + lastFont.paraMargin.bottom;\n  }\n  addString(str) {\n    if (!str) {\n      return;\n    }\n    const lastFont = this.fontSelector.topFont();\n    const fontSize = lastFont.xfaFont.size;\n    if (lastFont.pdfFont) {\n      const letterSpacing = lastFont.xfaFont.letterSpacing;\n      const pdfFont = lastFont.pdfFont;\n      const fontLineHeight = pdfFont.lineHeight || 1.2;\n      const lineHeight = lastFont.lineHeight || Math.max(1.2, fontLineHeight) * fontSize;\n      const lineGap = pdfFont.lineGap === undefined ? 0.2 : pdfFont.lineGap;\n      const noGap = fontLineHeight - lineGap;\n      const firstLineHeight = Math.max(1, noGap) * fontSize;\n      const scale = fontSize / 1000;\n      const fallbackWidth = pdfFont.defaultWidth || pdfFont.charsToGlyphs(\" \")[0].width;\n      for (const line of str.split(/[\\u2029\\n]/)) {\n        const encodedLine = pdfFont.encodeString(line).join(\"\");\n        const glyphs = pdfFont.charsToGlyphs(encodedLine);\n        for (const glyph of glyphs) {\n          const width = glyph.width || fallbackWidth;\n          this.glyphs.push([width * scale + letterSpacing, lineHeight, firstLineHeight, glyph.unicode, false]);\n        }\n        this.glyphs.push([0, 0, 0, \"\\n\", true]);\n      }\n      this.glyphs.pop();\n      return;\n    }\n    for (const line of str.split(/[\\u2029\\n]/)) {\n      for (const char of line.split(\"\")) {\n        this.glyphs.push([fontSize, 1.2 * fontSize, fontSize, char, false]);\n      }\n      this.glyphs.push([0, 0, 0, \"\\n\", true]);\n    }\n    this.glyphs.pop();\n  }\n  compute(maxWidth) {\n    let lastSpacePos = -1,\n      lastSpaceWidth = 0,\n      width = 0,\n      height = 0,\n      currentLineWidth = 0,\n      currentLineHeight = 0;\n    let isBroken = false;\n    let isFirstLine = true;\n    for (let i = 0, ii = this.glyphs.length; i < ii; i++) {\n      const [glyphWidth, lineHeight, firstLineHeight, char, isEOL] = this.glyphs[i];\n      const isSpace = char === \" \";\n      const glyphHeight = isFirstLine ? firstLineHeight : lineHeight;\n      if (isEOL) {\n        width = Math.max(width, currentLineWidth);\n        currentLineWidth = 0;\n        height += currentLineHeight;\n        currentLineHeight = glyphHeight;\n        lastSpacePos = -1;\n        lastSpaceWidth = 0;\n        isFirstLine = false;\n        continue;\n      }\n      if (isSpace) {\n        if (currentLineWidth + glyphWidth > maxWidth) {\n          width = Math.max(width, currentLineWidth);\n          currentLineWidth = 0;\n          height += currentLineHeight;\n          currentLineHeight = glyphHeight;\n          lastSpacePos = -1;\n          lastSpaceWidth = 0;\n          isBroken = true;\n          isFirstLine = false;\n        } else {\n          currentLineHeight = Math.max(glyphHeight, currentLineHeight);\n          lastSpaceWidth = currentLineWidth;\n          currentLineWidth += glyphWidth;\n          lastSpacePos = i;\n        }\n        continue;\n      }\n      if (currentLineWidth + glyphWidth > maxWidth) {\n        height += currentLineHeight;\n        currentLineHeight = glyphHeight;\n        if (lastSpacePos !== -1) {\n          i = lastSpacePos;\n          width = Math.max(width, lastSpaceWidth);\n          currentLineWidth = 0;\n          lastSpacePos = -1;\n          lastSpaceWidth = 0;\n        } else {\n          width = Math.max(width, currentLineWidth);\n          currentLineWidth = glyphWidth;\n        }\n        isBroken = true;\n        isFirstLine = false;\n        continue;\n      }\n      currentLineWidth += glyphWidth;\n      currentLineHeight = Math.max(glyphHeight, currentLineHeight);\n    }\n    width = Math.max(width, currentLineWidth);\n    height += currentLineHeight + this.extraHeight;\n    return {\n      width: WIDTH_FACTOR * width,\n      height,\n      isBroken\n    };\n  }\n}\n\n;// ./src/core/xfa/som.js\n\n\nconst namePattern = /^[^.[]+/;\nconst indexPattern = /^[^\\]]+/;\nconst operators = {\n  dot: 0,\n  dotDot: 1,\n  dotHash: 2,\n  dotBracket: 3,\n  dotParen: 4\n};\nconst shortcuts = new Map([[\"$data\", (root, current) => root.datasets ? root.datasets.data : root], [\"$record\", (root, current) => (root.datasets ? root.datasets.data : root)[$getChildren]()[0]], [\"$template\", (root, current) => root.template], [\"$connectionSet\", (root, current) => root.connectionSet], [\"$form\", (root, current) => root.form], [\"$layout\", (root, current) => root.layout], [\"$host\", (root, current) => root.host], [\"$dataWindow\", (root, current) => root.dataWindow], [\"$event\", (root, current) => root.event], [\"!\", (root, current) => root.datasets], [\"$xfa\", (root, current) => root], [\"xfa\", (root, current) => root], [\"$\", (root, current) => current]]);\nconst somCache = new WeakMap();\nfunction parseIndex(index) {\n  index = index.trim();\n  if (index === \"*\") {\n    return Infinity;\n  }\n  return parseInt(index, 10) || 0;\n}\nfunction parseExpression(expr, dotDotAllowed, noExpr = true) {\n  let match = expr.match(namePattern);\n  if (!match) {\n    return null;\n  }\n  let [name] = match;\n  const parsed = [{\n    name,\n    cacheName: \".\" + name,\n    index: 0,\n    js: null,\n    formCalc: null,\n    operator: operators.dot\n  }];\n  let pos = name.length;\n  while (pos < expr.length) {\n    const spos = pos;\n    const char = expr.charAt(pos++);\n    if (char === \"[\") {\n      match = expr.slice(pos).match(indexPattern);\n      if (!match) {\n        warn(\"XFA - Invalid index in SOM expression\");\n        return null;\n      }\n      parsed.at(-1).index = parseIndex(match[0]);\n      pos += match[0].length + 1;\n      continue;\n    }\n    let operator;\n    switch (expr.charAt(pos)) {\n      case \".\":\n        if (!dotDotAllowed) {\n          return null;\n        }\n        pos++;\n        operator = operators.dotDot;\n        break;\n      case \"#\":\n        pos++;\n        operator = operators.dotHash;\n        break;\n      case \"[\":\n        if (noExpr) {\n          warn(\"XFA - SOM expression contains a FormCalc subexpression which is not supported for now.\");\n          return null;\n        }\n        operator = operators.dotBracket;\n        break;\n      case \"(\":\n        if (noExpr) {\n          warn(\"XFA - SOM expression contains a JavaScript subexpression which is not supported for now.\");\n          return null;\n        }\n        operator = operators.dotParen;\n        break;\n      default:\n        operator = operators.dot;\n        break;\n    }\n    match = expr.slice(pos).match(namePattern);\n    if (!match) {\n      break;\n    }\n    [name] = match;\n    pos += name.length;\n    parsed.push({\n      name,\n      cacheName: expr.slice(spos, pos),\n      operator,\n      index: 0,\n      js: null,\n      formCalc: null\n    });\n  }\n  return parsed;\n}\nfunction searchNode(root, container, expr, dotDotAllowed = true, useCache = true) {\n  const parsed = parseExpression(expr, dotDotAllowed);\n  if (!parsed) {\n    return null;\n  }\n  const fn = shortcuts.get(parsed[0].name);\n  let i = 0;\n  let isQualified;\n  if (fn) {\n    isQualified = true;\n    root = [fn(root, container)];\n    i = 1;\n  } else {\n    isQualified = container === null;\n    root = [container || root];\n  }\n  for (let ii = parsed.length; i < ii; i++) {\n    const {\n      name,\n      cacheName,\n      operator,\n      index\n    } = parsed[i];\n    const nodes = [];\n    for (const node of root) {\n      if (!node.isXFAObject) {\n        continue;\n      }\n      let children, cached;\n      if (useCache) {\n        cached = somCache.get(node);\n        if (!cached) {\n          cached = new Map();\n          somCache.set(node, cached);\n        }\n        children = cached.get(cacheName);\n      }\n      if (!children) {\n        switch (operator) {\n          case operators.dot:\n            children = node[$getChildrenByName](name, false);\n            break;\n          case operators.dotDot:\n            children = node[$getChildrenByName](name, true);\n            break;\n          case operators.dotHash:\n            children = node[$getChildrenByClass](name);\n            children = children.isXFAObjectArray ? children.children : [children];\n            break;\n          default:\n            break;\n        }\n        if (useCache) {\n          cached.set(cacheName, children);\n        }\n      }\n      if (children.length > 0) {\n        nodes.push(children);\n      }\n    }\n    if (nodes.length === 0 && !isQualified && i === 0) {\n      const parent = container[$getParent]();\n      container = parent;\n      if (!container) {\n        return null;\n      }\n      i = -1;\n      root = [container];\n      continue;\n    }\n    root = isFinite(index) ? nodes.filter(node => index < node.length).map(node => node[index]) : nodes.flat();\n  }\n  if (root.length === 0) {\n    return null;\n  }\n  return root;\n}\nfunction createDataNode(root, container, expr) {\n  const parsed = parseExpression(expr);\n  if (!parsed) {\n    return null;\n  }\n  if (parsed.some(x => x.operator === operators.dotDot)) {\n    return null;\n  }\n  const fn = shortcuts.get(parsed[0].name);\n  let i = 0;\n  if (fn) {\n    root = fn(root, container);\n    i = 1;\n  } else {\n    root = container || root;\n  }\n  for (let ii = parsed.length; i < ii; i++) {\n    const {\n      name,\n      operator,\n      index\n    } = parsed[i];\n    if (!isFinite(index)) {\n      parsed[i].index = 0;\n      return root.createNodes(parsed.slice(i));\n    }\n    let children;\n    switch (operator) {\n      case operators.dot:\n        children = root[$getChildrenByName](name, false);\n        break;\n      case operators.dotDot:\n        children = root[$getChildrenByName](name, true);\n        break;\n      case operators.dotHash:\n        children = root[$getChildrenByClass](name);\n        children = children.isXFAObjectArray ? children.children : [children];\n        break;\n      default:\n        break;\n    }\n    if (children.length === 0) {\n      return root.createNodes(parsed.slice(i));\n    }\n    if (index < children.length) {\n      const child = children[index];\n      if (!child.isXFAObject) {\n        warn(`XFA - Cannot create a node.`);\n        return null;\n      }\n      root = child;\n    } else {\n      parsed[i].index = index - children.length;\n      return root.createNodes(parsed.slice(i));\n    }\n  }\n  return null;\n}\n\n;// ./src/core/xfa/xfa_object.js\n\n\n\n\n\n\nconst _applyPrototype = Symbol();\nconst _attributes = Symbol();\nconst _attributeNames = Symbol();\nconst _children = Symbol(\"_children\");\nconst _cloneAttribute = Symbol();\nconst _dataValue = Symbol();\nconst _defaultValue = Symbol();\nconst _filteredChildrenGenerator = Symbol();\nconst _getPrototype = Symbol();\nconst _getUnsetAttributes = Symbol();\nconst _hasChildren = Symbol();\nconst _max = Symbol();\nconst _options = Symbol();\nconst _parent = Symbol(\"parent\");\nconst _resolvePrototypesHelper = Symbol();\nconst _setAttributes = Symbol();\nconst _validator = Symbol();\nlet uid = 0;\nconst NS_DATASETS = NamespaceIds.datasets.id;\nclass XFAObject {\n  constructor(nsId, name, hasChildren = false) {\n    this[$namespaceId] = nsId;\n    this[$nodeName] = name;\n    this[_hasChildren] = hasChildren;\n    this[_parent] = null;\n    this[_children] = [];\n    this[$uid] = `${name}${uid++}`;\n    this[$globalData] = null;\n  }\n  get isXFAObject() {\n    return true;\n  }\n  get isXFAObjectArray() {\n    return false;\n  }\n  createNodes(path) {\n    let root = this,\n      node = null;\n    for (const {\n      name,\n      index\n    } of path) {\n      for (let i = 0, ii = isFinite(index) ? index : 0; i <= ii; i++) {\n        const nsId = root[$namespaceId] === NS_DATASETS ? -1 : root[$namespaceId];\n        node = new XmlObject(nsId, name);\n        root[$appendChild](node);\n      }\n      root = node;\n    }\n    return node;\n  }\n  [$onChild](child) {\n    if (!this[_hasChildren] || !this[$onChildCheck](child)) {\n      return false;\n    }\n    const name = child[$nodeName];\n    const node = this[name];\n    if (node instanceof XFAObjectArray) {\n      if (node.push(child)) {\n        this[$appendChild](child);\n        return true;\n      }\n    } else {\n      if (node !== null) {\n        this[$removeChild](node);\n      }\n      this[name] = child;\n      this[$appendChild](child);\n      return true;\n    }\n    let id = \"\";\n    if (this.id) {\n      id = ` (id: ${this.id})`;\n    } else if (this.name) {\n      id = ` (name: ${this.name} ${this.h.value})`;\n    }\n    warn(`XFA - node \"${this[$nodeName]}\"${id} has already enough \"${name}\"!`);\n    return false;\n  }\n  [$onChildCheck](child) {\n    return this.hasOwnProperty(child[$nodeName]) && child[$namespaceId] === this[$namespaceId];\n  }\n  [$isNsAgnostic]() {\n    return false;\n  }\n  [$acceptWhitespace]() {\n    return false;\n  }\n  [$isCDATAXml]() {\n    return false;\n  }\n  [$isBindable]() {\n    return false;\n  }\n  [$popPara]() {\n    if (this.para) {\n      this[$getTemplateRoot]()[$extra].paraStack.pop();\n    }\n  }\n  [$pushPara]() {\n    this[$getTemplateRoot]()[$extra].paraStack.push(this.para);\n  }\n  [$setId](ids) {\n    if (this.id && this[$namespaceId] === NamespaceIds.template.id) {\n      ids.set(this.id, this);\n    }\n  }\n  [$getTemplateRoot]() {\n    return this[$globalData].template;\n  }\n  [$isSplittable]() {\n    return false;\n  }\n  [$isThereMoreWidth]() {\n    return false;\n  }\n  [$appendChild](child) {\n    child[_parent] = this;\n    this[_children].push(child);\n    if (!child[$globalData] && this[$globalData]) {\n      child[$globalData] = this[$globalData];\n    }\n  }\n  [$removeChild](child) {\n    const i = this[_children].indexOf(child);\n    this[_children].splice(i, 1);\n  }\n  [$hasSettableValue]() {\n    return this.hasOwnProperty(\"value\");\n  }\n  [$setValue](_) {}\n  [$onText](_) {}\n  [$finalize]() {}\n  [$clean](builder) {\n    delete this[_hasChildren];\n    if (this[$cleanup]) {\n      builder.clean(this[$cleanup]);\n      delete this[$cleanup];\n    }\n  }\n  [$indexOf](child) {\n    return this[_children].indexOf(child);\n  }\n  [$insertAt](i, child) {\n    child[_parent] = this;\n    this[_children].splice(i, 0, child);\n    if (!child[$globalData] && this[$globalData]) {\n      child[$globalData] = this[$globalData];\n    }\n  }\n  [$isTransparent]() {\n    return !this.name;\n  }\n  [$lastAttribute]() {\n    return \"\";\n  }\n  [$text]() {\n    if (this[_children].length === 0) {\n      return this[$content];\n    }\n    return this[_children].map(c => c[$text]()).join(\"\");\n  }\n  get [_attributeNames]() {\n    const proto = Object.getPrototypeOf(this);\n    if (!proto._attributes) {\n      const attributes = proto._attributes = new Set();\n      for (const name of Object.getOwnPropertyNames(this)) {\n        if (this[name] === null || this[name] instanceof XFAObject || this[name] instanceof XFAObjectArray) {\n          break;\n        }\n        attributes.add(name);\n      }\n    }\n    return shadow(this, _attributeNames, proto._attributes);\n  }\n  [$isDescendent](parent) {\n    let node = this;\n    while (node) {\n      if (node === parent) {\n        return true;\n      }\n      node = node[$getParent]();\n    }\n    return false;\n  }\n  [$getParent]() {\n    return this[_parent];\n  }\n  [$getSubformParent]() {\n    return this[$getParent]();\n  }\n  [$getChildren](name = null) {\n    if (!name) {\n      return this[_children];\n    }\n    return this[name];\n  }\n  [$dump]() {\n    const dumped = Object.create(null);\n    if (this[$content]) {\n      dumped.$content = this[$content];\n    }\n    for (const name of Object.getOwnPropertyNames(this)) {\n      const value = this[name];\n      if (value === null) {\n        continue;\n      }\n      if (value instanceof XFAObject) {\n        dumped[name] = value[$dump]();\n      } else if (value instanceof XFAObjectArray) {\n        if (!value.isEmpty()) {\n          dumped[name] = value.dump();\n        }\n      } else {\n        dumped[name] = value;\n      }\n    }\n    return dumped;\n  }\n  [$toStyle]() {\n    return null;\n  }\n  [$toHTML]() {\n    return HTMLResult.EMPTY;\n  }\n  *[$getContainedChildren]() {\n    for (const node of this[$getChildren]()) {\n      yield node;\n    }\n  }\n  *[_filteredChildrenGenerator](filter, include) {\n    for (const node of this[$getContainedChildren]()) {\n      if (!filter || include === filter.has(node[$nodeName])) {\n        const availableSpace = this[$getAvailableSpace]();\n        const res = node[$toHTML](availableSpace);\n        if (!res.success) {\n          this[$extra].failingNode = node;\n        }\n        yield res;\n      }\n    }\n  }\n  [$flushHTML]() {\n    return null;\n  }\n  [$addHTML](html, bbox) {\n    this[$extra].children.push(html);\n  }\n  [$getAvailableSpace]() {}\n  [$childrenToHTML]({\n    filter = null,\n    include = true\n  }) {\n    if (!this[$extra].generator) {\n      this[$extra].generator = this[_filteredChildrenGenerator](filter, include);\n    } else {\n      const availableSpace = this[$getAvailableSpace]();\n      const res = this[$extra].failingNode[$toHTML](availableSpace);\n      if (!res.success) {\n        return res;\n      }\n      if (res.html) {\n        this[$addHTML](res.html, res.bbox);\n      }\n      delete this[$extra].failingNode;\n    }\n    while (true) {\n      const gen = this[$extra].generator.next();\n      if (gen.done) {\n        break;\n      }\n      const res = gen.value;\n      if (!res.success) {\n        return res;\n      }\n      if (res.html) {\n        this[$addHTML](res.html, res.bbox);\n      }\n    }\n    this[$extra].generator = null;\n    return HTMLResult.EMPTY;\n  }\n  [$setSetAttributes](attributes) {\n    this[_setAttributes] = new Set(Object.keys(attributes));\n  }\n  [_getUnsetAttributes](protoAttributes) {\n    const allAttr = this[_attributeNames];\n    const setAttr = this[_setAttributes];\n    return [...protoAttributes].filter(x => allAttr.has(x) && !setAttr.has(x));\n  }\n  [$resolvePrototypes](ids, ancestors = new Set()) {\n    for (const child of this[_children]) {\n      child[_resolvePrototypesHelper](ids, ancestors);\n    }\n  }\n  [_resolvePrototypesHelper](ids, ancestors) {\n    const proto = this[_getPrototype](ids, ancestors);\n    if (proto) {\n      this[_applyPrototype](proto, ids, ancestors);\n    } else {\n      this[$resolvePrototypes](ids, ancestors);\n    }\n  }\n  [_getPrototype](ids, ancestors) {\n    const {\n      use,\n      usehref\n    } = this;\n    if (!use && !usehref) {\n      return null;\n    }\n    let proto = null;\n    let somExpression = null;\n    let id = null;\n    let ref = use;\n    if (usehref) {\n      ref = usehref;\n      if (usehref.startsWith(\"#som(\") && usehref.endsWith(\")\")) {\n        somExpression = usehref.slice(\"#som(\".length, -1);\n      } else if (usehref.startsWith(\".#som(\") && usehref.endsWith(\")\")) {\n        somExpression = usehref.slice(\".#som(\".length, -1);\n      } else if (usehref.startsWith(\"#\")) {\n        id = usehref.slice(1);\n      } else if (usehref.startsWith(\".#\")) {\n        id = usehref.slice(2);\n      }\n    } else if (use.startsWith(\"#\")) {\n      id = use.slice(1);\n    } else {\n      somExpression = use;\n    }\n    this.use = this.usehref = \"\";\n    if (id) {\n      proto = ids.get(id);\n    } else {\n      proto = searchNode(ids.get($root), this, somExpression, true, false);\n      if (proto) {\n        proto = proto[0];\n      }\n    }\n    if (!proto) {\n      warn(`XFA - Invalid prototype reference: ${ref}.`);\n      return null;\n    }\n    if (proto[$nodeName] !== this[$nodeName]) {\n      warn(`XFA - Incompatible prototype: ${proto[$nodeName]} !== ${this[$nodeName]}.`);\n      return null;\n    }\n    if (ancestors.has(proto)) {\n      warn(`XFA - Cycle detected in prototypes use.`);\n      return null;\n    }\n    ancestors.add(proto);\n    const protoProto = proto[_getPrototype](ids, ancestors);\n    if (protoProto) {\n      proto[_applyPrototype](protoProto, ids, ancestors);\n    }\n    proto[$resolvePrototypes](ids, ancestors);\n    ancestors.delete(proto);\n    return proto;\n  }\n  [_applyPrototype](proto, ids, ancestors) {\n    if (ancestors.has(proto)) {\n      warn(`XFA - Cycle detected in prototypes use.`);\n      return;\n    }\n    if (!this[$content] && proto[$content]) {\n      this[$content] = proto[$content];\n    }\n    const newAncestors = new Set(ancestors);\n    newAncestors.add(proto);\n    for (const unsetAttrName of this[_getUnsetAttributes](proto[_setAttributes])) {\n      this[unsetAttrName] = proto[unsetAttrName];\n      if (this[_setAttributes]) {\n        this[_setAttributes].add(unsetAttrName);\n      }\n    }\n    for (const name of Object.getOwnPropertyNames(this)) {\n      if (this[_attributeNames].has(name)) {\n        continue;\n      }\n      const value = this[name];\n      const protoValue = proto[name];\n      if (value instanceof XFAObjectArray) {\n        for (const child of value[_children]) {\n          child[_resolvePrototypesHelper](ids, ancestors);\n        }\n        for (let i = value[_children].length, ii = protoValue[_children].length; i < ii; i++) {\n          const child = proto[_children][i][$clone]();\n          if (value.push(child)) {\n            child[_parent] = this;\n            this[_children].push(child);\n            child[_resolvePrototypesHelper](ids, ancestors);\n          } else {\n            break;\n          }\n        }\n        continue;\n      }\n      if (value !== null) {\n        value[$resolvePrototypes](ids, ancestors);\n        if (protoValue) {\n          value[_applyPrototype](protoValue, ids, ancestors);\n        }\n        continue;\n      }\n      if (protoValue !== null) {\n        const child = protoValue[$clone]();\n        child[_parent] = this;\n        this[name] = child;\n        this[_children].push(child);\n        child[_resolvePrototypesHelper](ids, ancestors);\n      }\n    }\n  }\n  static [_cloneAttribute](obj) {\n    if (Array.isArray(obj)) {\n      return obj.map(x => XFAObject[_cloneAttribute](x));\n    }\n    if (typeof obj === \"object\" && obj !== null) {\n      return Object.assign({}, obj);\n    }\n    return obj;\n  }\n  [$clone]() {\n    const clone = Object.create(Object.getPrototypeOf(this));\n    for (const $symbol of Object.getOwnPropertySymbols(this)) {\n      try {\n        clone[$symbol] = this[$symbol];\n      } catch {\n        shadow(clone, $symbol, this[$symbol]);\n      }\n    }\n    clone[$uid] = `${clone[$nodeName]}${uid++}`;\n    clone[_children] = [];\n    for (const name of Object.getOwnPropertyNames(this)) {\n      if (this[_attributeNames].has(name)) {\n        clone[name] = XFAObject[_cloneAttribute](this[name]);\n        continue;\n      }\n      const value = this[name];\n      clone[name] = value instanceof XFAObjectArray ? new XFAObjectArray(value[_max]) : null;\n    }\n    for (const child of this[_children]) {\n      const name = child[$nodeName];\n      const clonedChild = child[$clone]();\n      clone[_children].push(clonedChild);\n      clonedChild[_parent] = clone;\n      if (clone[name] === null) {\n        clone[name] = clonedChild;\n      } else {\n        clone[name][_children].push(clonedChild);\n      }\n    }\n    return clone;\n  }\n  [$getChildren](name = null) {\n    if (!name) {\n      return this[_children];\n    }\n    return this[_children].filter(c => c[$nodeName] === name);\n  }\n  [$getChildrenByClass](name) {\n    return this[name];\n  }\n  [$getChildrenByName](name, allTransparent, first = true) {\n    return Array.from(this[$getChildrenByNameIt](name, allTransparent, first));\n  }\n  *[$getChildrenByNameIt](name, allTransparent, first = true) {\n    if (name === \"parent\") {\n      yield this[_parent];\n      return;\n    }\n    for (const child of this[_children]) {\n      if (child[$nodeName] === name) {\n        yield child;\n      }\n      if (child.name === name) {\n        yield child;\n      }\n      if (allTransparent || child[$isTransparent]()) {\n        yield* child[$getChildrenByNameIt](name, allTransparent, false);\n      }\n    }\n    if (first && this[_attributeNames].has(name)) {\n      yield new XFAAttribute(this, name, this[name]);\n    }\n  }\n}\nclass XFAObjectArray {\n  constructor(max = Infinity) {\n    this[_max] = max;\n    this[_children] = [];\n  }\n  get isXFAObject() {\n    return false;\n  }\n  get isXFAObjectArray() {\n    return true;\n  }\n  push(child) {\n    const len = this[_children].length;\n    if (len <= this[_max]) {\n      this[_children].push(child);\n      return true;\n    }\n    warn(`XFA - node \"${child[$nodeName]}\" accepts no more than ${this[_max]} children`);\n    return false;\n  }\n  isEmpty() {\n    return this[_children].length === 0;\n  }\n  dump() {\n    return this[_children].length === 1 ? this[_children][0][$dump]() : this[_children].map(x => x[$dump]());\n  }\n  [$clone]() {\n    const clone = new XFAObjectArray(this[_max]);\n    clone[_children] = this[_children].map(c => c[$clone]());\n    return clone;\n  }\n  get children() {\n    return this[_children];\n  }\n  clear() {\n    this[_children].length = 0;\n  }\n}\nclass XFAAttribute {\n  constructor(node, name, value) {\n    this[_parent] = node;\n    this[$nodeName] = name;\n    this[$content] = value;\n    this[$consumed] = false;\n    this[$uid] = `attribute${uid++}`;\n  }\n  [$getParent]() {\n    return this[_parent];\n  }\n  [$isDataValue]() {\n    return true;\n  }\n  [$getDataValue]() {\n    return this[$content].trim();\n  }\n  [$setValue](value) {\n    value = value.value || \"\";\n    this[$content] = value.toString();\n  }\n  [$text]() {\n    return this[$content];\n  }\n  [$isDescendent](parent) {\n    return this[_parent] === parent || this[_parent][$isDescendent](parent);\n  }\n}\nclass XmlObject extends XFAObject {\n  constructor(nsId, name, attributes = {}) {\n    super(nsId, name);\n    this[$content] = \"\";\n    this[_dataValue] = null;\n    if (name !== \"#text\") {\n      const map = new Map();\n      this[_attributes] = map;\n      for (const [attrName, value] of Object.entries(attributes)) {\n        map.set(attrName, new XFAAttribute(this, attrName, value));\n      }\n      if (attributes.hasOwnProperty($nsAttributes)) {\n        const dataNode = attributes[$nsAttributes].xfa.dataNode;\n        if (dataNode !== undefined) {\n          if (dataNode === \"dataGroup\") {\n            this[_dataValue] = false;\n          } else if (dataNode === \"dataValue\") {\n            this[_dataValue] = true;\n          }\n        }\n      }\n    }\n    this[$consumed] = false;\n  }\n  [$toString](buf) {\n    const tagName = this[$nodeName];\n    if (tagName === \"#text\") {\n      buf.push(encodeToXmlString(this[$content]));\n      return;\n    }\n    const utf8TagName = utf8StringToString(tagName);\n    const prefix = this[$namespaceId] === NS_DATASETS ? \"xfa:\" : \"\";\n    buf.push(`<${prefix}${utf8TagName}`);\n    for (const [name, value] of this[_attributes].entries()) {\n      const utf8Name = utf8StringToString(name);\n      buf.push(` ${utf8Name}=\"${encodeToXmlString(value[$content])}\"`);\n    }\n    if (this[_dataValue] !== null) {\n      if (this[_dataValue]) {\n        buf.push(` xfa:dataNode=\"dataValue\"`);\n      } else {\n        buf.push(` xfa:dataNode=\"dataGroup\"`);\n      }\n    }\n    if (!this[$content] && this[_children].length === 0) {\n      buf.push(\"/>\");\n      return;\n    }\n    buf.push(\">\");\n    if (this[$content]) {\n      if (typeof this[$content] === \"string\") {\n        buf.push(encodeToXmlString(this[$content]));\n      } else {\n        this[$content][$toString](buf);\n      }\n    } else {\n      for (const child of this[_children]) {\n        child[$toString](buf);\n      }\n    }\n    buf.push(`</${prefix}${utf8TagName}>`);\n  }\n  [$onChild](child) {\n    if (this[$content]) {\n      const node = new XmlObject(this[$namespaceId], \"#text\");\n      this[$appendChild](node);\n      node[$content] = this[$content];\n      this[$content] = \"\";\n    }\n    this[$appendChild](child);\n    return true;\n  }\n  [$onText](str) {\n    this[$content] += str;\n  }\n  [$finalize]() {\n    if (this[$content] && this[_children].length > 0) {\n      const node = new XmlObject(this[$namespaceId], \"#text\");\n      this[$appendChild](node);\n      node[$content] = this[$content];\n      delete this[$content];\n    }\n  }\n  [$toHTML]() {\n    if (this[$nodeName] === \"#text\") {\n      return HTMLResult.success({\n        name: \"#text\",\n        value: this[$content]\n      });\n    }\n    return HTMLResult.EMPTY;\n  }\n  [$getChildren](name = null) {\n    if (!name) {\n      return this[_children];\n    }\n    return this[_children].filter(c => c[$nodeName] === name);\n  }\n  [$getAttributes]() {\n    return this[_attributes];\n  }\n  [$getChildrenByClass](name) {\n    const value = this[_attributes].get(name);\n    if (value !== undefined) {\n      return value;\n    }\n    return this[$getChildren](name);\n  }\n  *[$getChildrenByNameIt](name, allTransparent) {\n    const value = this[_attributes].get(name);\n    if (value) {\n      yield value;\n    }\n    for (const child of this[_children]) {\n      if (child[$nodeName] === name) {\n        yield child;\n      }\n      if (allTransparent) {\n        yield* child[$getChildrenByNameIt](name, allTransparent);\n      }\n    }\n  }\n  *[$getAttributeIt](name, skipConsumed) {\n    const value = this[_attributes].get(name);\n    if (value && (!skipConsumed || !value[$consumed])) {\n      yield value;\n    }\n    for (const child of this[_children]) {\n      yield* child[$getAttributeIt](name, skipConsumed);\n    }\n  }\n  *[$getRealChildrenByNameIt](name, allTransparent, skipConsumed) {\n    for (const child of this[_children]) {\n      if (child[$nodeName] === name && (!skipConsumed || !child[$consumed])) {\n        yield child;\n      }\n      if (allTransparent) {\n        yield* child[$getRealChildrenByNameIt](name, allTransparent, skipConsumed);\n      }\n    }\n  }\n  [$isDataValue]() {\n    if (this[_dataValue] === null) {\n      return this[_children].length === 0 || this[_children][0][$namespaceId] === NamespaceIds.xhtml.id;\n    }\n    return this[_dataValue];\n  }\n  [$getDataValue]() {\n    if (this[_dataValue] === null) {\n      if (this[_children].length === 0) {\n        return this[$content].trim();\n      }\n      if (this[_children][0][$namespaceId] === NamespaceIds.xhtml.id) {\n        return this[_children][0][$text]().trim();\n      }\n      return null;\n    }\n    return this[$content].trim();\n  }\n  [$setValue](value) {\n    value = value.value || \"\";\n    this[$content] = value.toString();\n  }\n  [$dump](hasNS = false) {\n    const dumped = Object.create(null);\n    if (hasNS) {\n      dumped.$ns = this[$namespaceId];\n    }\n    if (this[$content]) {\n      dumped.$content = this[$content];\n    }\n    dumped.$name = this[$nodeName];\n    dumped.children = [];\n    for (const child of this[_children]) {\n      dumped.children.push(child[$dump](hasNS));\n    }\n    dumped.attributes = Object.create(null);\n    for (const [name, value] of this[_attributes]) {\n      dumped.attributes[name] = value[$content];\n    }\n    return dumped;\n  }\n}\nclass ContentObject extends XFAObject {\n  constructor(nsId, name) {\n    super(nsId, name);\n    this[$content] = \"\";\n  }\n  [$onText](text) {\n    this[$content] += text;\n  }\n  [$finalize]() {}\n}\nclass OptionObject extends ContentObject {\n  constructor(nsId, name, options) {\n    super(nsId, name);\n    this[_options] = options;\n  }\n  [$finalize]() {\n    this[$content] = getKeyword({\n      data: this[$content],\n      defaultValue: this[_options][0],\n      validate: k => this[_options].includes(k)\n    });\n  }\n  [$clean](builder) {\n    super[$clean](builder);\n    delete this[_options];\n  }\n}\nclass StringObject extends ContentObject {\n  [$finalize]() {\n    this[$content] = this[$content].trim();\n  }\n}\nclass IntegerObject extends ContentObject {\n  constructor(nsId, name, defaultValue, validator) {\n    super(nsId, name);\n    this[_defaultValue] = defaultValue;\n    this[_validator] = validator;\n  }\n  [$finalize]() {\n    this[$content] = getInteger({\n      data: this[$content],\n      defaultValue: this[_defaultValue],\n      validate: this[_validator]\n    });\n  }\n  [$clean](builder) {\n    super[$clean](builder);\n    delete this[_defaultValue];\n    delete this[_validator];\n  }\n}\nclass Option01 extends IntegerObject {\n  constructor(nsId, name) {\n    super(nsId, name, 0, n => n === 1);\n  }\n}\nclass Option10 extends IntegerObject {\n  constructor(nsId, name) {\n    super(nsId, name, 1, n => n === 0);\n  }\n}\n\n;// ./src/core/xfa/html_utils.js\n\n\n\n\n\n\nfunction measureToString(m) {\n  if (typeof m === \"string\") {\n    return \"0px\";\n  }\n  return Number.isInteger(m) ? `${m}px` : `${m.toFixed(2)}px`;\n}\nconst converters = {\n  anchorType(node, style) {\n    const parent = node[$getSubformParent]();\n    if (!parent || parent.layout && parent.layout !== \"position\") {\n      return;\n    }\n    if (!(\"transform\" in style)) {\n      style.transform = \"\";\n    }\n    switch (node.anchorType) {\n      case \"bottomCenter\":\n        style.transform += \"translate(-50%, -100%)\";\n        break;\n      case \"bottomLeft\":\n        style.transform += \"translate(0,-100%)\";\n        break;\n      case \"bottomRight\":\n        style.transform += \"translate(-100%,-100%)\";\n        break;\n      case \"middleCenter\":\n        style.transform += \"translate(-50%,-50%)\";\n        break;\n      case \"middleLeft\":\n        style.transform += \"translate(0,-50%)\";\n        break;\n      case \"middleRight\":\n        style.transform += \"translate(-100%,-50%)\";\n        break;\n      case \"topCenter\":\n        style.transform += \"translate(-50%,0)\";\n        break;\n      case \"topRight\":\n        style.transform += \"translate(-100%,0)\";\n        break;\n    }\n  },\n  dimensions(node, style) {\n    const parent = node[$getSubformParent]();\n    let width = node.w;\n    const height = node.h;\n    if (parent.layout?.includes(\"row\")) {\n      const extra = parent[$extra];\n      const colSpan = node.colSpan;\n      let w;\n      if (colSpan === -1) {\n        w = extra.columnWidths.slice(extra.currentColumn).reduce((a, x) => a + x, 0);\n        extra.currentColumn = 0;\n      } else {\n        w = extra.columnWidths.slice(extra.currentColumn, extra.currentColumn + colSpan).reduce((a, x) => a + x, 0);\n        extra.currentColumn = (extra.currentColumn + node.colSpan) % extra.columnWidths.length;\n      }\n      if (!isNaN(w)) {\n        width = node.w = w;\n      }\n    }\n    style.width = width !== \"\" ? measureToString(width) : \"auto\";\n    style.height = height !== \"\" ? measureToString(height) : \"auto\";\n  },\n  position(node, style) {\n    const parent = node[$getSubformParent]();\n    if (parent?.layout && parent.layout !== \"position\") {\n      return;\n    }\n    style.position = \"absolute\";\n    style.left = measureToString(node.x);\n    style.top = measureToString(node.y);\n  },\n  rotate(node, style) {\n    if (node.rotate) {\n      if (!(\"transform\" in style)) {\n        style.transform = \"\";\n      }\n      style.transform += `rotate(-${node.rotate}deg)`;\n      style.transformOrigin = \"top left\";\n    }\n  },\n  presence(node, style) {\n    switch (node.presence) {\n      case \"invisible\":\n        style.visibility = \"hidden\";\n        break;\n      case \"hidden\":\n      case \"inactive\":\n        style.display = \"none\";\n        break;\n    }\n  },\n  hAlign(node, style) {\n    if (node[$nodeName] === \"para\") {\n      switch (node.hAlign) {\n        case \"justifyAll\":\n          style.textAlign = \"justify-all\";\n          break;\n        case \"radix\":\n          style.textAlign = \"left\";\n          break;\n        default:\n          style.textAlign = node.hAlign;\n      }\n    } else {\n      switch (node.hAlign) {\n        case \"left\":\n          style.alignSelf = \"start\";\n          break;\n        case \"center\":\n          style.alignSelf = \"center\";\n          break;\n        case \"right\":\n          style.alignSelf = \"end\";\n          break;\n      }\n    }\n  },\n  margin(node, style) {\n    if (node.margin) {\n      style.margin = node.margin[$toStyle]().margin;\n    }\n  }\n};\nfunction setMinMaxDimensions(node, style) {\n  const parent = node[$getSubformParent]();\n  if (parent.layout === \"position\") {\n    if (node.minW > 0) {\n      style.minWidth = measureToString(node.minW);\n    }\n    if (node.maxW > 0) {\n      style.maxWidth = measureToString(node.maxW);\n    }\n    if (node.minH > 0) {\n      style.minHeight = measureToString(node.minH);\n    }\n    if (node.maxH > 0) {\n      style.maxHeight = measureToString(node.maxH);\n    }\n  }\n}\nfunction layoutText(text, xfaFont, margin, lineHeight, fontFinder, width) {\n  const measure = new TextMeasure(xfaFont, margin, lineHeight, fontFinder);\n  if (typeof text === \"string\") {\n    measure.addString(text);\n  } else {\n    text[$pushGlyphs](measure);\n  }\n  return measure.compute(width);\n}\nfunction layoutNode(node, availableSpace) {\n  let height = null;\n  let width = null;\n  let isBroken = false;\n  if ((!node.w || !node.h) && node.value) {\n    let marginH = 0;\n    let marginV = 0;\n    if (node.margin) {\n      marginH = node.margin.leftInset + node.margin.rightInset;\n      marginV = node.margin.topInset + node.margin.bottomInset;\n    }\n    let lineHeight = null;\n    let margin = null;\n    if (node.para) {\n      margin = Object.create(null);\n      lineHeight = node.para.lineHeight === \"\" ? null : node.para.lineHeight;\n      margin.top = node.para.spaceAbove === \"\" ? 0 : node.para.spaceAbove;\n      margin.bottom = node.para.spaceBelow === \"\" ? 0 : node.para.spaceBelow;\n      margin.left = node.para.marginLeft === \"\" ? 0 : node.para.marginLeft;\n      margin.right = node.para.marginRight === \"\" ? 0 : node.para.marginRight;\n    }\n    let font = node.font;\n    if (!font) {\n      const root = node[$getTemplateRoot]();\n      let parent = node[$getParent]();\n      while (parent && parent !== root) {\n        if (parent.font) {\n          font = parent.font;\n          break;\n        }\n        parent = parent[$getParent]();\n      }\n    }\n    const maxWidth = (node.w || availableSpace.width) - marginH;\n    const fontFinder = node[$globalData].fontFinder;\n    if (node.value.exData && node.value.exData[$content] && node.value.exData.contentType === \"text/html\") {\n      const res = layoutText(node.value.exData[$content], font, margin, lineHeight, fontFinder, maxWidth);\n      width = res.width;\n      height = res.height;\n      isBroken = res.isBroken;\n    } else {\n      const text = node.value[$text]();\n      if (text) {\n        const res = layoutText(text, font, margin, lineHeight, fontFinder, maxWidth);\n        width = res.width;\n        height = res.height;\n        isBroken = res.isBroken;\n      }\n    }\n    if (width !== null && !node.w) {\n      width += marginH;\n    }\n    if (height !== null && !node.h) {\n      height += marginV;\n    }\n  }\n  return {\n    w: width,\n    h: height,\n    isBroken\n  };\n}\nfunction computeBbox(node, html, availableSpace) {\n  let bbox;\n  if (node.w !== \"\" && node.h !== \"\") {\n    bbox = [node.x, node.y, node.w, node.h];\n  } else {\n    if (!availableSpace) {\n      return null;\n    }\n    let width = node.w;\n    if (width === \"\") {\n      if (node.maxW === 0) {\n        const parent = node[$getSubformParent]();\n        width = parent.layout === \"position\" && parent.w !== \"\" ? 0 : node.minW;\n      } else {\n        width = Math.min(node.maxW, availableSpace.width);\n      }\n      html.attributes.style.width = measureToString(width);\n    }\n    let height = node.h;\n    if (height === \"\") {\n      if (node.maxH === 0) {\n        const parent = node[$getSubformParent]();\n        height = parent.layout === \"position\" && parent.h !== \"\" ? 0 : node.minH;\n      } else {\n        height = Math.min(node.maxH, availableSpace.height);\n      }\n      html.attributes.style.height = measureToString(height);\n    }\n    bbox = [node.x, node.y, width, height];\n  }\n  return bbox;\n}\nfunction fixDimensions(node) {\n  const parent = node[$getSubformParent]();\n  if (parent.layout?.includes(\"row\")) {\n    const extra = parent[$extra];\n    const colSpan = node.colSpan;\n    let width;\n    if (colSpan === -1) {\n      width = extra.columnWidths.slice(extra.currentColumn).reduce((a, w) => a + w, 0);\n    } else {\n      width = extra.columnWidths.slice(extra.currentColumn, extra.currentColumn + colSpan).reduce((a, w) => a + w, 0);\n    }\n    if (!isNaN(width)) {\n      node.w = width;\n    }\n  }\n  if (parent.layout && parent.layout !== \"position\") {\n    node.x = node.y = 0;\n  }\n  if (node.layout === \"table\") {\n    if (node.w === \"\" && Array.isArray(node.columnWidths)) {\n      node.w = node.columnWidths.reduce((a, x) => a + x, 0);\n    }\n  }\n}\nfunction layoutClass(node) {\n  switch (node.layout) {\n    case \"position\":\n      return \"xfaPosition\";\n    case \"lr-tb\":\n      return \"xfaLrTb\";\n    case \"rl-row\":\n      return \"xfaRlRow\";\n    case \"rl-tb\":\n      return \"xfaRlTb\";\n    case \"row\":\n      return \"xfaRow\";\n    case \"table\":\n      return \"xfaTable\";\n    case \"tb\":\n      return \"xfaTb\";\n    default:\n      return \"xfaPosition\";\n  }\n}\nfunction toStyle(node, ...names) {\n  const style = Object.create(null);\n  for (const name of names) {\n    const value = node[name];\n    if (value === null) {\n      continue;\n    }\n    if (converters.hasOwnProperty(name)) {\n      converters[name](node, style);\n      continue;\n    }\n    if (value instanceof XFAObject) {\n      const newStyle = value[$toStyle]();\n      if (newStyle) {\n        Object.assign(style, newStyle);\n      } else {\n        warn(`(DEBUG) - XFA - style for ${name} not implemented yet`);\n      }\n    }\n  }\n  return style;\n}\nfunction createWrapper(node, html) {\n  const {\n    attributes\n  } = html;\n  const {\n    style\n  } = attributes;\n  const wrapper = {\n    name: \"div\",\n    attributes: {\n      class: [\"xfaWrapper\"],\n      style: Object.create(null)\n    },\n    children: []\n  };\n  attributes.class.push(\"xfaWrapped\");\n  if (node.border) {\n    const {\n      widths,\n      insets\n    } = node.border[$extra];\n    let width, height;\n    let top = insets[0];\n    let left = insets[3];\n    const insetsH = insets[0] + insets[2];\n    const insetsW = insets[1] + insets[3];\n    switch (node.border.hand) {\n      case \"even\":\n        top -= widths[0] / 2;\n        left -= widths[3] / 2;\n        width = `calc(100% + ${(widths[1] + widths[3]) / 2 - insetsW}px)`;\n        height = `calc(100% + ${(widths[0] + widths[2]) / 2 - insetsH}px)`;\n        break;\n      case \"left\":\n        top -= widths[0];\n        left -= widths[3];\n        width = `calc(100% + ${widths[1] + widths[3] - insetsW}px)`;\n        height = `calc(100% + ${widths[0] + widths[2] - insetsH}px)`;\n        break;\n      case \"right\":\n        width = insetsW ? `calc(100% - ${insetsW}px)` : \"100%\";\n        height = insetsH ? `calc(100% - ${insetsH}px)` : \"100%\";\n        break;\n    }\n    const classNames = [\"xfaBorder\"];\n    if (isPrintOnly(node.border)) {\n      classNames.push(\"xfaPrintOnly\");\n    }\n    const border = {\n      name: \"div\",\n      attributes: {\n        class: classNames,\n        style: {\n          top: `${top}px`,\n          left: `${left}px`,\n          width,\n          height\n        }\n      },\n      children: []\n    };\n    for (const key of [\"border\", \"borderWidth\", \"borderColor\", \"borderRadius\", \"borderStyle\"]) {\n      if (style[key] !== undefined) {\n        border.attributes.style[key] = style[key];\n        delete style[key];\n      }\n    }\n    wrapper.children.push(border, html);\n  } else {\n    wrapper.children.push(html);\n  }\n  for (const key of [\"background\", \"backgroundClip\", \"top\", \"left\", \"width\", \"height\", \"minWidth\", \"minHeight\", \"maxWidth\", \"maxHeight\", \"transform\", \"transformOrigin\", \"visibility\"]) {\n    if (style[key] !== undefined) {\n      wrapper.attributes.style[key] = style[key];\n      delete style[key];\n    }\n  }\n  wrapper.attributes.style.position = style.position === \"absolute\" ? \"absolute\" : \"relative\";\n  delete style.position;\n  if (style.alignSelf) {\n    wrapper.attributes.style.alignSelf = style.alignSelf;\n    delete style.alignSelf;\n  }\n  return wrapper;\n}\nfunction fixTextIndent(styles) {\n  const indent = getMeasurement(styles.textIndent, \"0px\");\n  if (indent >= 0) {\n    return;\n  }\n  const align = styles.textAlign === \"right\" ? \"right\" : \"left\";\n  const name = \"padding\" + (align === \"left\" ? \"Left\" : \"Right\");\n  const padding = getMeasurement(styles[name], \"0px\");\n  styles[name] = `${padding - indent}px`;\n}\nfunction setAccess(node, classNames) {\n  switch (node.access) {\n    case \"nonInteractive\":\n      classNames.push(\"xfaNonInteractive\");\n      break;\n    case \"readOnly\":\n      classNames.push(\"xfaReadOnly\");\n      break;\n    case \"protected\":\n      classNames.push(\"xfaDisabled\");\n      break;\n  }\n}\nfunction isPrintOnly(node) {\n  return node.relevant.length > 0 && !node.relevant[0].excluded && node.relevant[0].viewname === \"print\";\n}\nfunction getCurrentPara(node) {\n  const stack = node[$getTemplateRoot]()[$extra].paraStack;\n  return stack.length ? stack.at(-1) : null;\n}\nfunction setPara(node, nodeStyle, value) {\n  if (value.attributes.class?.includes(\"xfaRich\")) {\n    if (nodeStyle) {\n      if (node.h === \"\") {\n        nodeStyle.height = \"auto\";\n      }\n      if (node.w === \"\") {\n        nodeStyle.width = \"auto\";\n      }\n    }\n    const para = getCurrentPara(node);\n    if (para) {\n      const valueStyle = value.attributes.style;\n      valueStyle.display = \"flex\";\n      valueStyle.flexDirection = \"column\";\n      switch (para.vAlign) {\n        case \"top\":\n          valueStyle.justifyContent = \"start\";\n          break;\n        case \"bottom\":\n          valueStyle.justifyContent = \"end\";\n          break;\n        case \"middle\":\n          valueStyle.justifyContent = \"center\";\n          break;\n      }\n      const paraStyle = para[$toStyle]();\n      for (const [key, val] of Object.entries(paraStyle)) {\n        if (!(key in valueStyle)) {\n          valueStyle[key] = val;\n        }\n      }\n    }\n  }\n}\nfunction setFontFamily(xfaFont, node, fontFinder, style) {\n  if (!fontFinder) {\n    delete style.fontFamily;\n    return;\n  }\n  const name = stripQuotes(xfaFont.typeface);\n  style.fontFamily = `\"${name}\"`;\n  const typeface = fontFinder.find(name);\n  if (typeface) {\n    const {\n      fontFamily\n    } = typeface.regular.cssFontInfo;\n    if (fontFamily !== name) {\n      style.fontFamily = `\"${fontFamily}\"`;\n    }\n    const para = getCurrentPara(node);\n    if (para && para.lineHeight !== \"\") {\n      return;\n    }\n    if (style.lineHeight) {\n      return;\n    }\n    const pdfFont = selectFont(xfaFont, typeface);\n    if (pdfFont) {\n      style.lineHeight = Math.max(1.2, pdfFont.lineHeight);\n    }\n  }\n}\nfunction fixURL(str) {\n  const absoluteUrl = createValidAbsoluteUrl(str, null, {\n    addDefaultProtocol: true,\n    tryConvertEncoding: true\n  });\n  return absoluteUrl ? absoluteUrl.href : null;\n}\n\n;// ./src/core/xfa/layout.js\n\n\nfunction createLine(node, children) {\n  return {\n    name: \"div\",\n    attributes: {\n      class: [node.layout === \"lr-tb\" ? \"xfaLr\" : \"xfaRl\"]\n    },\n    children\n  };\n}\nfunction flushHTML(node) {\n  if (!node[$extra]) {\n    return null;\n  }\n  const attributes = node[$extra].attributes;\n  const html = {\n    name: \"div\",\n    attributes,\n    children: node[$extra].children\n  };\n  if (node[$extra].failingNode) {\n    const htmlFromFailing = node[$extra].failingNode[$flushHTML]();\n    if (htmlFromFailing) {\n      if (node.layout.endsWith(\"-tb\")) {\n        html.children.push(createLine(node, [htmlFromFailing]));\n      } else {\n        html.children.push(htmlFromFailing);\n      }\n    }\n  }\n  if (html.children.length === 0) {\n    return null;\n  }\n  return html;\n}\nfunction addHTML(node, html, bbox) {\n  const extra = node[$extra];\n  const availableSpace = extra.availableSpace;\n  const [x, y, w, h] = bbox;\n  switch (node.layout) {\n    case \"position\":\n      {\n        extra.width = Math.max(extra.width, x + w);\n        extra.height = Math.max(extra.height, y + h);\n        extra.children.push(html);\n        break;\n      }\n    case \"lr-tb\":\n    case \"rl-tb\":\n      if (!extra.line || extra.attempt === 1) {\n        extra.line = createLine(node, []);\n        extra.children.push(extra.line);\n        extra.numberInLine = 0;\n      }\n      extra.numberInLine += 1;\n      extra.line.children.push(html);\n      if (extra.attempt === 0) {\n        extra.currentWidth += w;\n        extra.height = Math.max(extra.height, extra.prevHeight + h);\n      } else {\n        extra.currentWidth = w;\n        extra.prevHeight = extra.height;\n        extra.height += h;\n        extra.attempt = 0;\n      }\n      extra.width = Math.max(extra.width, extra.currentWidth);\n      break;\n    case \"rl-row\":\n    case \"row\":\n      {\n        extra.children.push(html);\n        extra.width += w;\n        extra.height = Math.max(extra.height, h);\n        const height = measureToString(extra.height);\n        for (const child of extra.children) {\n          child.attributes.style.height = height;\n        }\n        break;\n      }\n    case \"table\":\n      {\n        extra.width = Math.min(availableSpace.width, Math.max(extra.width, w));\n        extra.height += h;\n        extra.children.push(html);\n        break;\n      }\n    case \"tb\":\n      {\n        extra.width = Math.min(availableSpace.width, Math.max(extra.width, w));\n        extra.height += h;\n        extra.children.push(html);\n        break;\n      }\n  }\n}\nfunction getAvailableSpace(node) {\n  const availableSpace = node[$extra].availableSpace;\n  const marginV = node.margin ? node.margin.topInset + node.margin.bottomInset : 0;\n  const marginH = node.margin ? node.margin.leftInset + node.margin.rightInset : 0;\n  switch (node.layout) {\n    case \"lr-tb\":\n    case \"rl-tb\":\n      if (node[$extra].attempt === 0) {\n        return {\n          width: availableSpace.width - marginH - node[$extra].currentWidth,\n          height: availableSpace.height - marginV - node[$extra].prevHeight\n        };\n      }\n      return {\n        width: availableSpace.width - marginH,\n        height: availableSpace.height - marginV - node[$extra].height\n      };\n    case \"rl-row\":\n    case \"row\":\n      const width = node[$extra].columnWidths.slice(node[$extra].currentColumn).reduce((a, x) => a + x);\n      return {\n        width,\n        height: availableSpace.height - marginH\n      };\n    case \"table\":\n    case \"tb\":\n      return {\n        width: availableSpace.width - marginH,\n        height: availableSpace.height - marginV - node[$extra].height\n      };\n    case \"position\":\n    default:\n      return availableSpace;\n  }\n}\nfunction getTransformedBBox(node) {\n  let w = node.w === \"\" ? NaN : node.w;\n  let h = node.h === \"\" ? NaN : node.h;\n  let [centerX, centerY] = [0, 0];\n  switch (node.anchorType || \"\") {\n    case \"bottomCenter\":\n      [centerX, centerY] = [w / 2, h];\n      break;\n    case \"bottomLeft\":\n      [centerX, centerY] = [0, h];\n      break;\n    case \"bottomRight\":\n      [centerX, centerY] = [w, h];\n      break;\n    case \"middleCenter\":\n      [centerX, centerY] = [w / 2, h / 2];\n      break;\n    case \"middleLeft\":\n      [centerX, centerY] = [0, h / 2];\n      break;\n    case \"middleRight\":\n      [centerX, centerY] = [w, h / 2];\n      break;\n    case \"topCenter\":\n      [centerX, centerY] = [w / 2, 0];\n      break;\n    case \"topRight\":\n      [centerX, centerY] = [w, 0];\n      break;\n  }\n  let x, y;\n  switch (node.rotate || 0) {\n    case 0:\n      [x, y] = [-centerX, -centerY];\n      break;\n    case 90:\n      [x, y] = [-centerY, centerX];\n      [w, h] = [h, -w];\n      break;\n    case 180:\n      [x, y] = [centerX, centerY];\n      [w, h] = [-w, -h];\n      break;\n    case 270:\n      [x, y] = [centerY, -centerX];\n      [w, h] = [-h, w];\n      break;\n  }\n  return [node.x + x + Math.min(0, w), node.y + y + Math.min(0, h), Math.abs(w), Math.abs(h)];\n}\nfunction checkDimensions(node, space) {\n  if (node[$getTemplateRoot]()[$extra].firstUnsplittable === null) {\n    return true;\n  }\n  if (node.w === 0 || node.h === 0) {\n    return true;\n  }\n  const ERROR = 2;\n  const parent = node[$getSubformParent]();\n  const attempt = parent[$extra]?.attempt || 0;\n  const [, y, w, h] = getTransformedBBox(node);\n  switch (parent.layout) {\n    case \"lr-tb\":\n    case \"rl-tb\":\n      if (attempt === 0) {\n        if (!node[$getTemplateRoot]()[$extra].noLayoutFailure) {\n          if (node.h !== \"\" && Math.round(h - space.height) > ERROR) {\n            return false;\n          }\n          if (node.w !== \"\") {\n            if (Math.round(w - space.width) <= ERROR) {\n              return true;\n            }\n            if (parent[$extra].numberInLine === 0) {\n              return space.height > ERROR;\n            }\n            return false;\n          }\n          return space.width > ERROR;\n        }\n        if (node.w !== \"\") {\n          return Math.round(w - space.width) <= ERROR;\n        }\n        return space.width > ERROR;\n      }\n      if (node[$getTemplateRoot]()[$extra].noLayoutFailure) {\n        return true;\n      }\n      if (node.h !== \"\" && Math.round(h - space.height) > ERROR) {\n        return false;\n      }\n      if (node.w === \"\" || Math.round(w - space.width) <= ERROR) {\n        return space.height > ERROR;\n      }\n      if (parent[$isThereMoreWidth]()) {\n        return false;\n      }\n      return space.height > ERROR;\n    case \"table\":\n    case \"tb\":\n      if (node[$getTemplateRoot]()[$extra].noLayoutFailure) {\n        return true;\n      }\n      if (node.h !== \"\" && !node[$isSplittable]()) {\n        return Math.round(h - space.height) <= ERROR;\n      }\n      if (node.w === \"\" || Math.round(w - space.width) <= ERROR) {\n        return space.height > ERROR;\n      }\n      if (parent[$isThereMoreWidth]()) {\n        return false;\n      }\n      return space.height > ERROR;\n    case \"position\":\n      if (node[$getTemplateRoot]()[$extra].noLayoutFailure) {\n        return true;\n      }\n      if (node.h === \"\" || Math.round(h + y - space.height) <= ERROR) {\n        return true;\n      }\n      const area = node[$getTemplateRoot]()[$extra].currentContentArea;\n      return h + y > area.h;\n    case \"rl-row\":\n    case \"row\":\n      if (node[$getTemplateRoot]()[$extra].noLayoutFailure) {\n        return true;\n      }\n      if (node.h !== \"\") {\n        return Math.round(h - space.height) <= ERROR;\n      }\n      return true;\n    default:\n      return true;\n  }\n}\n\n;// ./src/core/xfa/template.js\n\n\n\n\n\n\n\n\n\n\nconst TEMPLATE_NS_ID = NamespaceIds.template.id;\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\nconst MAX_ATTEMPTS_FOR_LRTB_LAYOUT = 2;\nconst MAX_EMPTY_PAGES = 3;\nconst DEFAULT_TAB_INDEX = 5000;\nconst HEADING_PATTERN = /^H(\\d+)$/;\nconst MIMES = new Set([\"image/gif\", \"image/jpeg\", \"image/jpg\", \"image/pjpeg\", \"image/png\", \"image/apng\", \"image/x-png\", \"image/bmp\", \"image/x-ms-bmp\", \"image/tiff\", \"image/tif\", \"application/octet-stream\"]);\nconst IMAGES_HEADERS = [[[0x42, 0x4d], \"image/bmp\"], [[0xff, 0xd8, 0xff], \"image/jpeg\"], [[0x49, 0x49, 0x2a, 0x00], \"image/tiff\"], [[0x4d, 0x4d, 0x00, 0x2a], \"image/tiff\"], [[0x47, 0x49, 0x46, 0x38, 0x39, 0x61], \"image/gif\"], [[0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a], \"image/png\"]];\nfunction getBorderDims(node) {\n  if (!node || !node.border) {\n    return {\n      w: 0,\n      h: 0\n    };\n  }\n  const borderExtra = node.border[$getExtra]();\n  if (!borderExtra) {\n    return {\n      w: 0,\n      h: 0\n    };\n  }\n  return {\n    w: borderExtra.widths[0] + borderExtra.widths[2] + borderExtra.insets[0] + borderExtra.insets[2],\n    h: borderExtra.widths[1] + borderExtra.widths[3] + borderExtra.insets[1] + borderExtra.insets[3]\n  };\n}\nfunction hasMargin(node) {\n  return node.margin && (node.margin.topInset || node.margin.rightInset || node.margin.bottomInset || node.margin.leftInset);\n}\nfunction _setValue(templateNode, value) {\n  if (!templateNode.value) {\n    const nodeValue = new Value({});\n    templateNode[$appendChild](nodeValue);\n    templateNode.value = nodeValue;\n  }\n  templateNode.value[$setValue](value);\n}\nfunction* getContainedChildren(node) {\n  for (const child of node[$getChildren]()) {\n    if (child instanceof SubformSet) {\n      yield* child[$getContainedChildren]();\n      continue;\n    }\n    yield child;\n  }\n}\nfunction isRequired(node) {\n  return node.validate?.nullTest === \"error\";\n}\nfunction setTabIndex(node) {\n  while (node) {\n    if (!node.traversal) {\n      node[$tabIndex] = node[$getParent]()[$tabIndex];\n      return;\n    }\n    if (node[$tabIndex]) {\n      return;\n    }\n    let next = null;\n    for (const child of node.traversal[$getChildren]()) {\n      if (child.operation === \"next\") {\n        next = child;\n        break;\n      }\n    }\n    if (!next || !next.ref) {\n      node[$tabIndex] = node[$getParent]()[$tabIndex];\n      return;\n    }\n    const root = node[$getTemplateRoot]();\n    node[$tabIndex] = ++root[$tabIndex];\n    const ref = root[$searchNode](next.ref, node);\n    if (!ref) {\n      return;\n    }\n    node = ref[0];\n  }\n}\nfunction applyAssist(obj, attributes) {\n  const assist = obj.assist;\n  if (assist) {\n    const assistTitle = assist[$toHTML]();\n    if (assistTitle) {\n      attributes.title = assistTitle;\n    }\n    const role = assist.role;\n    const match = role.match(HEADING_PATTERN);\n    if (match) {\n      const ariaRole = \"heading\";\n      const ariaLevel = match[1];\n      attributes.role = ariaRole;\n      attributes[\"aria-level\"] = ariaLevel;\n    }\n  }\n  if (obj.layout === \"table\") {\n    attributes.role = \"table\";\n  } else if (obj.layout === \"row\") {\n    attributes.role = \"row\";\n  } else {\n    const parent = obj[$getParent]();\n    if (parent.layout === \"row\") {\n      attributes.role = parent.assist?.role === \"TH\" ? \"columnheader\" : \"cell\";\n    }\n  }\n}\nfunction ariaLabel(obj) {\n  if (!obj.assist) {\n    return null;\n  }\n  const assist = obj.assist;\n  if (assist.speak && assist.speak[$content] !== \"\") {\n    return assist.speak[$content];\n  }\n  if (assist.toolTip) {\n    return assist.toolTip[$content];\n  }\n  return null;\n}\nfunction valueToHtml(value) {\n  return HTMLResult.success({\n    name: \"div\",\n    attributes: {\n      class: [\"xfaRich\"],\n      style: Object.create(null)\n    },\n    children: [{\n      name: \"span\",\n      attributes: {\n        style: Object.create(null)\n      },\n      value\n    }]\n  });\n}\nfunction setFirstUnsplittable(node) {\n  const root = node[$getTemplateRoot]();\n  if (root[$extra].firstUnsplittable === null) {\n    root[$extra].firstUnsplittable = node;\n    root[$extra].noLayoutFailure = true;\n  }\n}\nfunction unsetFirstUnsplittable(node) {\n  const root = node[$getTemplateRoot]();\n  if (root[$extra].firstUnsplittable === node) {\n    root[$extra].noLayoutFailure = false;\n  }\n}\nfunction handleBreak(node) {\n  if (node[$extra]) {\n    return false;\n  }\n  node[$extra] = Object.create(null);\n  if (node.targetType === \"auto\") {\n    return false;\n  }\n  const root = node[$getTemplateRoot]();\n  let target = null;\n  if (node.target) {\n    target = root[$searchNode](node.target, node[$getParent]());\n    if (!target) {\n      return false;\n    }\n    target = target[0];\n  }\n  const {\n    currentPageArea,\n    currentContentArea\n  } = root[$extra];\n  if (node.targetType === \"pageArea\") {\n    if (!(target instanceof PageArea)) {\n      target = null;\n    }\n    if (node.startNew) {\n      node[$extra].target = target || currentPageArea;\n      return true;\n    } else if (target && target !== currentPageArea) {\n      node[$extra].target = target;\n      return true;\n    }\n    return false;\n  }\n  if (!(target instanceof ContentArea)) {\n    target = null;\n  }\n  const pageArea = target && target[$getParent]();\n  let index;\n  let nextPageArea = pageArea;\n  if (node.startNew) {\n    if (target) {\n      const contentAreas = pageArea.contentArea.children;\n      const indexForCurrent = contentAreas.indexOf(currentContentArea);\n      const indexForTarget = contentAreas.indexOf(target);\n      if (indexForCurrent !== -1 && indexForCurrent < indexForTarget) {\n        nextPageArea = null;\n      }\n      index = indexForTarget - 1;\n    } else {\n      index = currentPageArea.contentArea.children.indexOf(currentContentArea);\n    }\n  } else if (target && target !== currentContentArea) {\n    const contentAreas = pageArea.contentArea.children;\n    index = contentAreas.indexOf(target) - 1;\n    nextPageArea = pageArea === currentPageArea ? null : pageArea;\n  } else {\n    return false;\n  }\n  node[$extra].target = nextPageArea;\n  node[$extra].index = index;\n  return true;\n}\nfunction handleOverflow(node, extraNode, space) {\n  const root = node[$getTemplateRoot]();\n  const saved = root[$extra].noLayoutFailure;\n  const savedMethod = extraNode[$getSubformParent];\n  extraNode[$getSubformParent] = () => node;\n  root[$extra].noLayoutFailure = true;\n  const res = extraNode[$toHTML](space);\n  node[$addHTML](res.html, res.bbox);\n  root[$extra].noLayoutFailure = saved;\n  extraNode[$getSubformParent] = savedMethod;\n}\nclass AppearanceFilter extends StringObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"appearanceFilter\");\n    this.id = attributes.id || \"\";\n    this.type = getStringOption(attributes.type, [\"optional\", \"required\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass Arc extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"arc\", true);\n    this.circular = getInteger({\n      data: attributes.circular,\n      defaultValue: 0,\n      validate: x => x === 1\n    });\n    this.hand = getStringOption(attributes.hand, [\"even\", \"left\", \"right\"]);\n    this.id = attributes.id || \"\";\n    this.startAngle = getFloat({\n      data: attributes.startAngle,\n      defaultValue: 0,\n      validate: x => true\n    });\n    this.sweepAngle = getFloat({\n      data: attributes.sweepAngle,\n      defaultValue: 360,\n      validate: x => true\n    });\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.edge = null;\n    this.fill = null;\n  }\n  [$toHTML]() {\n    const edge = this.edge || new Edge({});\n    const edgeStyle = edge[$toStyle]();\n    const style = Object.create(null);\n    if (this.fill?.presence === \"visible\") {\n      Object.assign(style, this.fill[$toStyle]());\n    } else {\n      style.fill = \"transparent\";\n    }\n    style.strokeWidth = measureToString(edge.presence === \"visible\" ? edge.thickness : 0);\n    style.stroke = edgeStyle.color;\n    let arc;\n    const attributes = {\n      xmlns: SVG_NS,\n      style: {\n        width: \"100%\",\n        height: \"100%\",\n        overflow: \"visible\"\n      }\n    };\n    if (this.sweepAngle === 360) {\n      arc = {\n        name: \"ellipse\",\n        attributes: {\n          xmlns: SVG_NS,\n          cx: \"50%\",\n          cy: \"50%\",\n          rx: \"50%\",\n          ry: \"50%\",\n          style\n        }\n      };\n    } else {\n      const startAngle = this.startAngle * Math.PI / 180;\n      const sweepAngle = this.sweepAngle * Math.PI / 180;\n      const largeArc = this.sweepAngle > 180 ? 1 : 0;\n      const [x1, y1, x2, y2] = [50 * (1 + Math.cos(startAngle)), 50 * (1 - Math.sin(startAngle)), 50 * (1 + Math.cos(startAngle + sweepAngle)), 50 * (1 - Math.sin(startAngle + sweepAngle))];\n      arc = {\n        name: \"path\",\n        attributes: {\n          xmlns: SVG_NS,\n          d: `M ${x1} ${y1} A 50 50 0 ${largeArc} 0 ${x2} ${y2}`,\n          vectorEffect: \"non-scaling-stroke\",\n          style\n        }\n      };\n      Object.assign(attributes, {\n        viewBox: \"0 0 100 100\",\n        preserveAspectRatio: \"none\"\n      });\n    }\n    const svg = {\n      name: \"svg\",\n      children: [arc],\n      attributes\n    };\n    const parent = this[$getParent]()[$getParent]();\n    if (hasMargin(parent)) {\n      return HTMLResult.success({\n        name: \"div\",\n        attributes: {\n          style: {\n            display: \"inline\",\n            width: \"100%\",\n            height: \"100%\"\n          }\n        },\n        children: [svg]\n      });\n    }\n    svg.attributes.style.position = \"absolute\";\n    return HTMLResult.success(svg);\n  }\n}\nclass Area extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"area\", true);\n    this.colSpan = getInteger({\n      data: attributes.colSpan,\n      defaultValue: 1,\n      validate: n => n >= 1 || n === -1\n    });\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.relevant = getRelevant(attributes.relevant);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.x = getMeasurement(attributes.x, \"0pt\");\n    this.y = getMeasurement(attributes.y, \"0pt\");\n    this.desc = null;\n    this.extras = null;\n    this.area = new XFAObjectArray();\n    this.draw = new XFAObjectArray();\n    this.exObject = new XFAObjectArray();\n    this.exclGroup = new XFAObjectArray();\n    this.field = new XFAObjectArray();\n    this.subform = new XFAObjectArray();\n    this.subformSet = new XFAObjectArray();\n  }\n  *[$getContainedChildren]() {\n    yield* getContainedChildren(this);\n  }\n  [$isTransparent]() {\n    return true;\n  }\n  [$isBindable]() {\n    return true;\n  }\n  [$addHTML](html, bbox) {\n    const [x, y, w, h] = bbox;\n    this[$extra].width = Math.max(this[$extra].width, x + w);\n    this[$extra].height = Math.max(this[$extra].height, y + h);\n    this[$extra].children.push(html);\n  }\n  [$getAvailableSpace]() {\n    return this[$extra].availableSpace;\n  }\n  [$toHTML](availableSpace) {\n    const style = toStyle(this, \"position\");\n    const attributes = {\n      style,\n      id: this[$uid],\n      class: [\"xfaArea\"]\n    };\n    if (isPrintOnly(this)) {\n      attributes.class.push(\"xfaPrintOnly\");\n    }\n    if (this.name) {\n      attributes.xfaName = this.name;\n    }\n    const children = [];\n    this[$extra] = {\n      children,\n      width: 0,\n      height: 0,\n      availableSpace\n    };\n    const result = this[$childrenToHTML]({\n      filter: new Set([\"area\", \"draw\", \"field\", \"exclGroup\", \"subform\", \"subformSet\"]),\n      include: true\n    });\n    if (!result.success) {\n      if (result.isBreak()) {\n        return result;\n      }\n      delete this[$extra];\n      return HTMLResult.FAILURE;\n    }\n    style.width = measureToString(this[$extra].width);\n    style.height = measureToString(this[$extra].height);\n    const html = {\n      name: \"div\",\n      attributes,\n      children\n    };\n    const bbox = [this.x, this.y, this[$extra].width, this[$extra].height];\n    delete this[$extra];\n    return HTMLResult.success(html, bbox);\n  }\n}\nclass Assist extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"assist\", true);\n    this.id = attributes.id || \"\";\n    this.role = attributes.role || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.speak = null;\n    this.toolTip = null;\n  }\n  [$toHTML]() {\n    return this.toolTip?.[$content] || null;\n  }\n}\nclass Barcode extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"barcode\", true);\n    this.charEncoding = getKeyword({\n      data: attributes.charEncoding ? attributes.charEncoding.toLowerCase() : \"\",\n      defaultValue: \"\",\n      validate: k => [\"utf-8\", \"big-five\", \"fontspecific\", \"gbk\", \"gb-18030\", \"gb-2312\", \"ksc-5601\", \"none\", \"shift-jis\", \"ucs-2\", \"utf-16\"].includes(k) || k.match(/iso-8859-\\d{2}/)\n    });\n    this.checksum = getStringOption(attributes.checksum, [\"none\", \"1mod10\", \"1mod10_1mod11\", \"2mod10\", \"auto\"]);\n    this.dataColumnCount = getInteger({\n      data: attributes.dataColumnCount,\n      defaultValue: -1,\n      validate: x => x >= 0\n    });\n    this.dataLength = getInteger({\n      data: attributes.dataLength,\n      defaultValue: -1,\n      validate: x => x >= 0\n    });\n    this.dataPrep = getStringOption(attributes.dataPrep, [\"none\", \"flateCompress\"]);\n    this.dataRowCount = getInteger({\n      data: attributes.dataRowCount,\n      defaultValue: -1,\n      validate: x => x >= 0\n    });\n    this.endChar = attributes.endChar || \"\";\n    this.errorCorrectionLevel = getInteger({\n      data: attributes.errorCorrectionLevel,\n      defaultValue: -1,\n      validate: x => x >= 0 && x <= 8\n    });\n    this.id = attributes.id || \"\";\n    this.moduleHeight = getMeasurement(attributes.moduleHeight, \"5mm\");\n    this.moduleWidth = getMeasurement(attributes.moduleWidth, \"0.25mm\");\n    this.printCheckDigit = getInteger({\n      data: attributes.printCheckDigit,\n      defaultValue: 0,\n      validate: x => x === 1\n    });\n    this.rowColumnRatio = getRatio(attributes.rowColumnRatio);\n    this.startChar = attributes.startChar || \"\";\n    this.textLocation = getStringOption(attributes.textLocation, [\"below\", \"above\", \"aboveEmbedded\", \"belowEmbedded\", \"none\"]);\n    this.truncate = getInteger({\n      data: attributes.truncate,\n      defaultValue: 0,\n      validate: x => x === 1\n    });\n    this.type = getStringOption(attributes.type ? attributes.type.toLowerCase() : \"\", [\"aztec\", \"codabar\", \"code2of5industrial\", \"code2of5interleaved\", \"code2of5matrix\", \"code2of5standard\", \"code3of9\", \"code3of9extended\", \"code11\", \"code49\", \"code93\", \"code128\", \"code128a\", \"code128b\", \"code128c\", \"code128sscc\", \"datamatrix\", \"ean8\", \"ean8add2\", \"ean8add5\", \"ean13\", \"ean13add2\", \"ean13add5\", \"ean13pwcd\", \"fim\", \"logmars\", \"maxicode\", \"msi\", \"pdf417\", \"pdf417macro\", \"plessey\", \"postauscust2\", \"postauscust3\", \"postausreplypaid\", \"postausstandard\", \"postukrm4scc\", \"postusdpbc\", \"postusimb\", \"postusstandard\", \"postus5zip\", \"qrcode\", \"rfid\", \"rss14\", \"rss14expanded\", \"rss14limited\", \"rss14stacked\", \"rss14stackedomni\", \"rss14truncated\", \"telepen\", \"ucc128\", \"ucc128random\", \"ucc128sscc\", \"upca\", \"upcaadd2\", \"upcaadd5\", \"upcapwcd\", \"upce\", \"upceadd2\", \"upceadd5\", \"upcean2\", \"upcean5\", \"upsmaxicode\"]);\n    this.upsMode = getStringOption(attributes.upsMode, [\"usCarrier\", \"internationalCarrier\", \"secureSymbol\", \"standardSymbol\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.wideNarrowRatio = getRatio(attributes.wideNarrowRatio);\n    this.encrypt = null;\n    this.extras = null;\n  }\n}\nclass Bind extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"bind\", true);\n    this.match = getStringOption(attributes.match, [\"once\", \"dataRef\", \"global\", \"none\"]);\n    this.ref = attributes.ref || \"\";\n    this.picture = null;\n  }\n}\nclass BindItems extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"bindItems\");\n    this.connection = attributes.connection || \"\";\n    this.labelRef = attributes.labelRef || \"\";\n    this.ref = attributes.ref || \"\";\n    this.valueRef = attributes.valueRef || \"\";\n  }\n}\nclass Bookend extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"bookend\");\n    this.id = attributes.id || \"\";\n    this.leader = attributes.leader || \"\";\n    this.trailer = attributes.trailer || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass BooleanElement extends Option01 {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"boolean\");\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n  [$toHTML](availableSpace) {\n    return valueToHtml(this[$content] === 1 ? \"1\" : \"0\");\n  }\n}\nclass Border extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"border\", true);\n    this.break = getStringOption(attributes.break, [\"close\", \"open\"]);\n    this.hand = getStringOption(attributes.hand, [\"even\", \"left\", \"right\"]);\n    this.id = attributes.id || \"\";\n    this.presence = getStringOption(attributes.presence, [\"visible\", \"hidden\", \"inactive\", \"invisible\"]);\n    this.relevant = getRelevant(attributes.relevant);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.corner = new XFAObjectArray(4);\n    this.edge = new XFAObjectArray(4);\n    this.extras = null;\n    this.fill = null;\n    this.margin = null;\n  }\n  [$getExtra]() {\n    if (!this[$extra]) {\n      const edges = this.edge.children.slice();\n      if (edges.length < 4) {\n        const defaultEdge = edges.at(-1) || new Edge({});\n        for (let i = edges.length; i < 4; i++) {\n          edges.push(defaultEdge);\n        }\n      }\n      const widths = edges.map(edge => edge.thickness);\n      const insets = [0, 0, 0, 0];\n      if (this.margin) {\n        insets[0] = this.margin.topInset;\n        insets[1] = this.margin.rightInset;\n        insets[2] = this.margin.bottomInset;\n        insets[3] = this.margin.leftInset;\n      }\n      this[$extra] = {\n        widths,\n        insets,\n        edges\n      };\n    }\n    return this[$extra];\n  }\n  [$toStyle]() {\n    const {\n      edges\n    } = this[$getExtra]();\n    const edgeStyles = edges.map(node => {\n      const style = node[$toStyle]();\n      style.color ||= \"#000000\";\n      return style;\n    });\n    const style = Object.create(null);\n    if (this.margin) {\n      Object.assign(style, this.margin[$toStyle]());\n    }\n    if (this.fill?.presence === \"visible\") {\n      Object.assign(style, this.fill[$toStyle]());\n    }\n    if (this.corner.children.some(node => node.radius !== 0)) {\n      const cornerStyles = this.corner.children.map(node => node[$toStyle]());\n      if (cornerStyles.length === 2 || cornerStyles.length === 3) {\n        const last = cornerStyles.at(-1);\n        for (let i = cornerStyles.length; i < 4; i++) {\n          cornerStyles.push(last);\n        }\n      }\n      style.borderRadius = cornerStyles.map(s => s.radius).join(\" \");\n    }\n    switch (this.presence) {\n      case \"invisible\":\n      case \"hidden\":\n        style.borderStyle = \"\";\n        break;\n      case \"inactive\":\n        style.borderStyle = \"none\";\n        break;\n      default:\n        style.borderStyle = edgeStyles.map(s => s.style).join(\" \");\n        break;\n    }\n    style.borderWidth = edgeStyles.map(s => s.width).join(\" \");\n    style.borderColor = edgeStyles.map(s => s.color).join(\" \");\n    return style;\n  }\n}\nclass Break extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"break\", true);\n    this.after = getStringOption(attributes.after, [\"auto\", \"contentArea\", \"pageArea\", \"pageEven\", \"pageOdd\"]);\n    this.afterTarget = attributes.afterTarget || \"\";\n    this.before = getStringOption(attributes.before, [\"auto\", \"contentArea\", \"pageArea\", \"pageEven\", \"pageOdd\"]);\n    this.beforeTarget = attributes.beforeTarget || \"\";\n    this.bookendLeader = attributes.bookendLeader || \"\";\n    this.bookendTrailer = attributes.bookendTrailer || \"\";\n    this.id = attributes.id || \"\";\n    this.overflowLeader = attributes.overflowLeader || \"\";\n    this.overflowTarget = attributes.overflowTarget || \"\";\n    this.overflowTrailer = attributes.overflowTrailer || \"\";\n    this.startNew = getInteger({\n      data: attributes.startNew,\n      defaultValue: 0,\n      validate: x => x === 1\n    });\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.extras = null;\n  }\n}\nclass BreakAfter extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"breakAfter\", true);\n    this.id = attributes.id || \"\";\n    this.leader = attributes.leader || \"\";\n    this.startNew = getInteger({\n      data: attributes.startNew,\n      defaultValue: 0,\n      validate: x => x === 1\n    });\n    this.target = attributes.target || \"\";\n    this.targetType = getStringOption(attributes.targetType, [\"auto\", \"contentArea\", \"pageArea\"]);\n    this.trailer = attributes.trailer || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.script = null;\n  }\n}\nclass BreakBefore extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"breakBefore\", true);\n    this.id = attributes.id || \"\";\n    this.leader = attributes.leader || \"\";\n    this.startNew = getInteger({\n      data: attributes.startNew,\n      defaultValue: 0,\n      validate: x => x === 1\n    });\n    this.target = attributes.target || \"\";\n    this.targetType = getStringOption(attributes.targetType, [\"auto\", \"contentArea\", \"pageArea\"]);\n    this.trailer = attributes.trailer || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.script = null;\n  }\n  [$toHTML](availableSpace) {\n    this[$extra] = {};\n    return HTMLResult.FAILURE;\n  }\n}\nclass Button extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"button\", true);\n    this.highlight = getStringOption(attributes.highlight, [\"inverted\", \"none\", \"outline\", \"push\"]);\n    this.id = attributes.id || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.extras = null;\n  }\n  [$toHTML](availableSpace) {\n    const parent = this[$getParent]();\n    const grandpa = parent[$getParent]();\n    const htmlButton = {\n      name: \"button\",\n      attributes: {\n        id: this[$uid],\n        class: [\"xfaButton\"],\n        style: {}\n      },\n      children: []\n    };\n    for (const event of grandpa.event.children) {\n      if (event.activity !== \"click\" || !event.script) {\n        continue;\n      }\n      const jsURL = recoverJsURL(event.script[$content]);\n      if (!jsURL) {\n        continue;\n      }\n      const href = fixURL(jsURL.url);\n      if (!href) {\n        continue;\n      }\n      htmlButton.children.push({\n        name: \"a\",\n        attributes: {\n          id: \"link\" + this[$uid],\n          href,\n          newWindow: jsURL.newWindow,\n          class: [\"xfaLink\"],\n          style: {}\n        },\n        children: []\n      });\n    }\n    return HTMLResult.success(htmlButton);\n  }\n}\nclass Calculate extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"calculate\", true);\n    this.id = attributes.id || \"\";\n    this.override = getStringOption(attributes.override, [\"disabled\", \"error\", \"ignore\", \"warning\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.extras = null;\n    this.message = null;\n    this.script = null;\n  }\n}\nclass Caption extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"caption\", true);\n    this.id = attributes.id || \"\";\n    this.placement = getStringOption(attributes.placement, [\"left\", \"bottom\", \"inline\", \"right\", \"top\"]);\n    this.presence = getStringOption(attributes.presence, [\"visible\", \"hidden\", \"inactive\", \"invisible\"]);\n    this.reserve = Math.ceil(getMeasurement(attributes.reserve));\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.extras = null;\n    this.font = null;\n    this.margin = null;\n    this.para = null;\n    this.value = null;\n  }\n  [$setValue](value) {\n    _setValue(this, value);\n  }\n  [$getExtra](availableSpace) {\n    if (!this[$extra]) {\n      let {\n        width,\n        height\n      } = availableSpace;\n      switch (this.placement) {\n        case \"left\":\n        case \"right\":\n        case \"inline\":\n          width = this.reserve <= 0 ? width : this.reserve;\n          break;\n        case \"top\":\n        case \"bottom\":\n          height = this.reserve <= 0 ? height : this.reserve;\n          break;\n      }\n      this[$extra] = layoutNode(this, {\n        width,\n        height\n      });\n    }\n    return this[$extra];\n  }\n  [$toHTML](availableSpace) {\n    if (!this.value) {\n      return HTMLResult.EMPTY;\n    }\n    this[$pushPara]();\n    const value = this.value[$toHTML](availableSpace).html;\n    if (!value) {\n      this[$popPara]();\n      return HTMLResult.EMPTY;\n    }\n    const savedReserve = this.reserve;\n    if (this.reserve <= 0) {\n      const {\n        w,\n        h\n      } = this[$getExtra](availableSpace);\n      switch (this.placement) {\n        case \"left\":\n        case \"right\":\n        case \"inline\":\n          this.reserve = w;\n          break;\n        case \"top\":\n        case \"bottom\":\n          this.reserve = h;\n          break;\n      }\n    }\n    const children = [];\n    if (typeof value === \"string\") {\n      children.push({\n        name: \"#text\",\n        value\n      });\n    } else {\n      children.push(value);\n    }\n    const style = toStyle(this, \"font\", \"margin\", \"visibility\");\n    switch (this.placement) {\n      case \"left\":\n      case \"right\":\n        if (this.reserve > 0) {\n          style.width = measureToString(this.reserve);\n        }\n        break;\n      case \"top\":\n      case \"bottom\":\n        if (this.reserve > 0) {\n          style.height = measureToString(this.reserve);\n        }\n        break;\n    }\n    setPara(this, null, value);\n    this[$popPara]();\n    this.reserve = savedReserve;\n    return HTMLResult.success({\n      name: \"div\",\n      attributes: {\n        style,\n        class: [\"xfaCaption\"]\n      },\n      children\n    });\n  }\n}\nclass Certificate extends StringObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"certificate\");\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass Certificates extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"certificates\", true);\n    this.credentialServerPolicy = getStringOption(attributes.credentialServerPolicy, [\"optional\", \"required\"]);\n    this.id = attributes.id || \"\";\n    this.url = attributes.url || \"\";\n    this.urlPolicy = attributes.urlPolicy || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.encryption = null;\n    this.issuers = null;\n    this.keyUsage = null;\n    this.oids = null;\n    this.signing = null;\n    this.subjectDNs = null;\n  }\n}\nclass CheckButton extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"checkButton\", true);\n    this.id = attributes.id || \"\";\n    this.mark = getStringOption(attributes.mark, [\"default\", \"check\", \"circle\", \"cross\", \"diamond\", \"square\", \"star\"]);\n    this.shape = getStringOption(attributes.shape, [\"square\", \"round\"]);\n    this.size = getMeasurement(attributes.size, \"10pt\");\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.border = null;\n    this.extras = null;\n    this.margin = null;\n  }\n  [$toHTML](availableSpace) {\n    const style = toStyle(\"margin\");\n    const size = measureToString(this.size);\n    style.width = style.height = size;\n    let type;\n    let className;\n    let groupId;\n    const field = this[$getParent]()[$getParent]();\n    const items = field.items.children.length && field.items.children[0][$toHTML]().html || [];\n    const exportedValue = {\n      on: (items[0] !== undefined ? items[0] : \"on\").toString(),\n      off: (items[1] !== undefined ? items[1] : \"off\").toString()\n    };\n    const value = field.value?.[$text]() || \"off\";\n    const checked = value === exportedValue.on || undefined;\n    const container = field[$getSubformParent]();\n    const fieldId = field[$uid];\n    let dataId;\n    if (container instanceof ExclGroup) {\n      groupId = container[$uid];\n      type = \"radio\";\n      className = \"xfaRadio\";\n      dataId = container[$data]?.[$uid] || container[$uid];\n    } else {\n      type = \"checkbox\";\n      className = \"xfaCheckbox\";\n      dataId = field[$data]?.[$uid] || field[$uid];\n    }\n    const input = {\n      name: \"input\",\n      attributes: {\n        class: [className],\n        style,\n        fieldId,\n        dataId,\n        type,\n        checked,\n        xfaOn: exportedValue.on,\n        xfaOff: exportedValue.off,\n        \"aria-label\": ariaLabel(field),\n        \"aria-required\": false\n      }\n    };\n    if (groupId) {\n      input.attributes.name = groupId;\n    }\n    if (isRequired(field)) {\n      input.attributes[\"aria-required\"] = true;\n      input.attributes.required = true;\n    }\n    return HTMLResult.success({\n      name: \"label\",\n      attributes: {\n        class: [\"xfaLabel\"]\n      },\n      children: [input]\n    });\n  }\n}\nclass ChoiceList extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"choiceList\", true);\n    this.commitOn = getStringOption(attributes.commitOn, [\"select\", \"exit\"]);\n    this.id = attributes.id || \"\";\n    this.open = getStringOption(attributes.open, [\"userControl\", \"always\", \"multiSelect\", \"onEntry\"]);\n    this.textEntry = getInteger({\n      data: attributes.textEntry,\n      defaultValue: 0,\n      validate: x => x === 1\n    });\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.border = null;\n    this.extras = null;\n    this.margin = null;\n  }\n  [$toHTML](availableSpace) {\n    const style = toStyle(this, \"border\", \"margin\");\n    const ui = this[$getParent]();\n    const field = ui[$getParent]();\n    const fontSize = field.font?.size || 10;\n    const optionStyle = {\n      fontSize: `calc(${fontSize}px * var(--scale-factor))`\n    };\n    const children = [];\n    if (field.items.children.length > 0) {\n      const items = field.items;\n      let displayedIndex = 0;\n      let saveIndex = 0;\n      if (items.children.length === 2) {\n        displayedIndex = items.children[0].save;\n        saveIndex = 1 - displayedIndex;\n      }\n      const displayed = items.children[displayedIndex][$toHTML]().html;\n      const values = items.children[saveIndex][$toHTML]().html;\n      let selected = false;\n      const value = field.value?.[$text]() || \"\";\n      for (let i = 0, ii = displayed.length; i < ii; i++) {\n        const option = {\n          name: \"option\",\n          attributes: {\n            value: values[i] || displayed[i],\n            style: optionStyle\n          },\n          value: displayed[i]\n        };\n        if (values[i] === value) {\n          option.attributes.selected = selected = true;\n        }\n        children.push(option);\n      }\n      if (!selected) {\n        children.splice(0, 0, {\n          name: \"option\",\n          attributes: {\n            hidden: true,\n            selected: true\n          },\n          value: \" \"\n        });\n      }\n    }\n    const selectAttributes = {\n      class: [\"xfaSelect\"],\n      fieldId: field[$uid],\n      dataId: field[$data]?.[$uid] || field[$uid],\n      style,\n      \"aria-label\": ariaLabel(field),\n      \"aria-required\": false\n    };\n    if (isRequired(field)) {\n      selectAttributes[\"aria-required\"] = true;\n      selectAttributes.required = true;\n    }\n    if (this.open === \"multiSelect\") {\n      selectAttributes.multiple = true;\n    }\n    return HTMLResult.success({\n      name: \"label\",\n      attributes: {\n        class: [\"xfaLabel\"]\n      },\n      children: [{\n        name: \"select\",\n        children,\n        attributes: selectAttributes\n      }]\n    });\n  }\n}\nclass Color extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"color\", true);\n    this.cSpace = getStringOption(attributes.cSpace, [\"SRGB\"]);\n    this.id = attributes.id || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.value = attributes.value ? getColor(attributes.value) : \"\";\n    this.extras = null;\n  }\n  [$hasSettableValue]() {\n    return false;\n  }\n  [$toStyle]() {\n    return this.value ? Util.makeHexColor(this.value.r, this.value.g, this.value.b) : null;\n  }\n}\nclass Comb extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"comb\");\n    this.id = attributes.id || \"\";\n    this.numberOfCells = getInteger({\n      data: attributes.numberOfCells,\n      defaultValue: 0,\n      validate: x => x >= 0\n    });\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass Connect extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"connect\", true);\n    this.connection = attributes.connection || \"\";\n    this.id = attributes.id || \"\";\n    this.ref = attributes.ref || \"\";\n    this.usage = getStringOption(attributes.usage, [\"exportAndImport\", \"exportOnly\", \"importOnly\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.picture = null;\n  }\n}\nclass ContentArea extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"contentArea\", true);\n    this.h = getMeasurement(attributes.h);\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.relevant = getRelevant(attributes.relevant);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.w = getMeasurement(attributes.w);\n    this.x = getMeasurement(attributes.x, \"0pt\");\n    this.y = getMeasurement(attributes.y, \"0pt\");\n    this.desc = null;\n    this.extras = null;\n  }\n  [$toHTML](availableSpace) {\n    const left = measureToString(this.x);\n    const top = measureToString(this.y);\n    const style = {\n      left,\n      top,\n      width: measureToString(this.w),\n      height: measureToString(this.h)\n    };\n    const classNames = [\"xfaContentarea\"];\n    if (isPrintOnly(this)) {\n      classNames.push(\"xfaPrintOnly\");\n    }\n    return HTMLResult.success({\n      name: \"div\",\n      children: [],\n      attributes: {\n        style,\n        class: classNames,\n        id: this[$uid]\n      }\n    });\n  }\n}\nclass Corner extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"corner\", true);\n    this.id = attributes.id || \"\";\n    this.inverted = getInteger({\n      data: attributes.inverted,\n      defaultValue: 0,\n      validate: x => x === 1\n    });\n    this.join = getStringOption(attributes.join, [\"square\", \"round\"]);\n    this.presence = getStringOption(attributes.presence, [\"visible\", \"hidden\", \"inactive\", \"invisible\"]);\n    this.radius = getMeasurement(attributes.radius);\n    this.stroke = getStringOption(attributes.stroke, [\"solid\", \"dashDot\", \"dashDotDot\", \"dashed\", \"dotted\", \"embossed\", \"etched\", \"lowered\", \"raised\"]);\n    this.thickness = getMeasurement(attributes.thickness, \"0.5pt\");\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.color = null;\n    this.extras = null;\n  }\n  [$toStyle]() {\n    const style = toStyle(this, \"visibility\");\n    style.radius = measureToString(this.join === \"square\" ? 0 : this.radius);\n    return style;\n  }\n}\nclass DateElement extends ContentObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"date\");\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n  [$finalize]() {\n    const date = this[$content].trim();\n    this[$content] = date ? new Date(date) : null;\n  }\n  [$toHTML](availableSpace) {\n    return valueToHtml(this[$content] ? this[$content].toString() : \"\");\n  }\n}\nclass DateTime extends ContentObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"dateTime\");\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n  [$finalize]() {\n    const date = this[$content].trim();\n    this[$content] = date ? new Date(date) : null;\n  }\n  [$toHTML](availableSpace) {\n    return valueToHtml(this[$content] ? this[$content].toString() : \"\");\n  }\n}\nclass DateTimeEdit extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"dateTimeEdit\", true);\n    this.hScrollPolicy = getStringOption(attributes.hScrollPolicy, [\"auto\", \"off\", \"on\"]);\n    this.id = attributes.id || \"\";\n    this.picker = getStringOption(attributes.picker, [\"host\", \"none\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.border = null;\n    this.comb = null;\n    this.extras = null;\n    this.margin = null;\n  }\n  [$toHTML](availableSpace) {\n    const style = toStyle(this, \"border\", \"font\", \"margin\");\n    const field = this[$getParent]()[$getParent]();\n    const html = {\n      name: \"input\",\n      attributes: {\n        type: \"text\",\n        fieldId: field[$uid],\n        dataId: field[$data]?.[$uid] || field[$uid],\n        class: [\"xfaTextfield\"],\n        style,\n        \"aria-label\": ariaLabel(field),\n        \"aria-required\": false\n      }\n    };\n    if (isRequired(field)) {\n      html.attributes[\"aria-required\"] = true;\n      html.attributes.required = true;\n    }\n    return HTMLResult.success({\n      name: \"label\",\n      attributes: {\n        class: [\"xfaLabel\"]\n      },\n      children: [html]\n    });\n  }\n}\nclass Decimal extends ContentObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"decimal\");\n    this.fracDigits = getInteger({\n      data: attributes.fracDigits,\n      defaultValue: 2,\n      validate: x => true\n    });\n    this.id = attributes.id || \"\";\n    this.leadDigits = getInteger({\n      data: attributes.leadDigits,\n      defaultValue: -1,\n      validate: x => true\n    });\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n  [$finalize]() {\n    const number = parseFloat(this[$content].trim());\n    this[$content] = isNaN(number) ? null : number;\n  }\n  [$toHTML](availableSpace) {\n    return valueToHtml(this[$content] !== null ? this[$content].toString() : \"\");\n  }\n}\nclass DefaultUi extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"defaultUi\", true);\n    this.id = attributes.id || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.extras = null;\n  }\n}\nclass Desc extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"desc\", true);\n    this.id = attributes.id || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.boolean = new XFAObjectArray();\n    this.date = new XFAObjectArray();\n    this.dateTime = new XFAObjectArray();\n    this.decimal = new XFAObjectArray();\n    this.exData = new XFAObjectArray();\n    this.float = new XFAObjectArray();\n    this.image = new XFAObjectArray();\n    this.integer = new XFAObjectArray();\n    this.text = new XFAObjectArray();\n    this.time = new XFAObjectArray();\n  }\n}\nclass DigestMethod extends OptionObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"digestMethod\", [\"\", \"SHA1\", \"SHA256\", \"SHA512\", \"RIPEMD160\"]);\n    this.id = attributes.id || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass DigestMethods extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"digestMethods\", true);\n    this.id = attributes.id || \"\";\n    this.type = getStringOption(attributes.type, [\"optional\", \"required\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.digestMethod = new XFAObjectArray();\n  }\n}\nclass Draw extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"draw\", true);\n    this.anchorType = getStringOption(attributes.anchorType, [\"topLeft\", \"bottomCenter\", \"bottomLeft\", \"bottomRight\", \"middleCenter\", \"middleLeft\", \"middleRight\", \"topCenter\", \"topRight\"]);\n    this.colSpan = getInteger({\n      data: attributes.colSpan,\n      defaultValue: 1,\n      validate: n => n >= 1 || n === -1\n    });\n    this.h = attributes.h ? getMeasurement(attributes.h) : \"\";\n    this.hAlign = getStringOption(attributes.hAlign, [\"left\", \"center\", \"justify\", \"justifyAll\", \"radix\", \"right\"]);\n    this.id = attributes.id || \"\";\n    this.locale = attributes.locale || \"\";\n    this.maxH = getMeasurement(attributes.maxH, \"0pt\");\n    this.maxW = getMeasurement(attributes.maxW, \"0pt\");\n    this.minH = getMeasurement(attributes.minH, \"0pt\");\n    this.minW = getMeasurement(attributes.minW, \"0pt\");\n    this.name = attributes.name || \"\";\n    this.presence = getStringOption(attributes.presence, [\"visible\", \"hidden\", \"inactive\", \"invisible\"]);\n    this.relevant = getRelevant(attributes.relevant);\n    this.rotate = getInteger({\n      data: attributes.rotate,\n      defaultValue: 0,\n      validate: x => x % 90 === 0\n    });\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.w = attributes.w ? getMeasurement(attributes.w) : \"\";\n    this.x = getMeasurement(attributes.x, \"0pt\");\n    this.y = getMeasurement(attributes.y, \"0pt\");\n    this.assist = null;\n    this.border = null;\n    this.caption = null;\n    this.desc = null;\n    this.extras = null;\n    this.font = null;\n    this.keep = null;\n    this.margin = null;\n    this.para = null;\n    this.traversal = null;\n    this.ui = null;\n    this.value = null;\n    this.setProperty = new XFAObjectArray();\n  }\n  [$setValue](value) {\n    _setValue(this, value);\n  }\n  [$toHTML](availableSpace) {\n    setTabIndex(this);\n    if (this.presence === \"hidden\" || this.presence === \"inactive\") {\n      return HTMLResult.EMPTY;\n    }\n    fixDimensions(this);\n    this[$pushPara]();\n    const savedW = this.w;\n    const savedH = this.h;\n    const {\n      w,\n      h,\n      isBroken\n    } = layoutNode(this, availableSpace);\n    if (w && this.w === \"\") {\n      if (isBroken && this[$getSubformParent]()[$isThereMoreWidth]()) {\n        this[$popPara]();\n        return HTMLResult.FAILURE;\n      }\n      this.w = w;\n    }\n    if (h && this.h === \"\") {\n      this.h = h;\n    }\n    setFirstUnsplittable(this);\n    if (!checkDimensions(this, availableSpace)) {\n      this.w = savedW;\n      this.h = savedH;\n      this[$popPara]();\n      return HTMLResult.FAILURE;\n    }\n    unsetFirstUnsplittable(this);\n    const style = toStyle(this, \"font\", \"hAlign\", \"dimensions\", \"position\", \"presence\", \"rotate\", \"anchorType\", \"border\", \"margin\");\n    setMinMaxDimensions(this, style);\n    if (style.margin) {\n      style.padding = style.margin;\n      delete style.margin;\n    }\n    const classNames = [\"xfaDraw\"];\n    if (this.font) {\n      classNames.push(\"xfaFont\");\n    }\n    if (isPrintOnly(this)) {\n      classNames.push(\"xfaPrintOnly\");\n    }\n    const attributes = {\n      style,\n      id: this[$uid],\n      class: classNames\n    };\n    if (this.name) {\n      attributes.xfaName = this.name;\n    }\n    const html = {\n      name: \"div\",\n      attributes,\n      children: []\n    };\n    applyAssist(this, attributes);\n    const bbox = computeBbox(this, html, availableSpace);\n    const value = this.value ? this.value[$toHTML](availableSpace).html : null;\n    if (value === null) {\n      this.w = savedW;\n      this.h = savedH;\n      this[$popPara]();\n      return HTMLResult.success(createWrapper(this, html), bbox);\n    }\n    html.children.push(value);\n    setPara(this, style, value);\n    this.w = savedW;\n    this.h = savedH;\n    this[$popPara]();\n    return HTMLResult.success(createWrapper(this, html), bbox);\n  }\n}\nclass Edge extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"edge\", true);\n    this.cap = getStringOption(attributes.cap, [\"square\", \"butt\", \"round\"]);\n    this.id = attributes.id || \"\";\n    this.presence = getStringOption(attributes.presence, [\"visible\", \"hidden\", \"inactive\", \"invisible\"]);\n    this.stroke = getStringOption(attributes.stroke, [\"solid\", \"dashDot\", \"dashDotDot\", \"dashed\", \"dotted\", \"embossed\", \"etched\", \"lowered\", \"raised\"]);\n    this.thickness = getMeasurement(attributes.thickness, \"0.5pt\");\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.color = null;\n    this.extras = null;\n  }\n  [$toStyle]() {\n    const style = toStyle(this, \"visibility\");\n    Object.assign(style, {\n      linecap: this.cap,\n      width: measureToString(this.thickness),\n      color: this.color ? this.color[$toStyle]() : \"#000000\",\n      style: \"\"\n    });\n    if (this.presence !== \"visible\") {\n      style.style = \"none\";\n    } else {\n      switch (this.stroke) {\n        case \"solid\":\n          style.style = \"solid\";\n          break;\n        case \"dashDot\":\n          style.style = \"dashed\";\n          break;\n        case \"dashDotDot\":\n          style.style = \"dashed\";\n          break;\n        case \"dashed\":\n          style.style = \"dashed\";\n          break;\n        case \"dotted\":\n          style.style = \"dotted\";\n          break;\n        case \"embossed\":\n          style.style = \"ridge\";\n          break;\n        case \"etched\":\n          style.style = \"groove\";\n          break;\n        case \"lowered\":\n          style.style = \"inset\";\n          break;\n        case \"raised\":\n          style.style = \"outset\";\n          break;\n      }\n    }\n    return style;\n  }\n}\nclass Encoding extends OptionObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"encoding\", [\"adbe.x509.rsa_sha1\", \"adbe.pkcs7.detached\", \"adbe.pkcs7.sha1\"]);\n    this.id = attributes.id || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass Encodings extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"encodings\", true);\n    this.id = attributes.id || \"\";\n    this.type = getStringOption(attributes.type, [\"optional\", \"required\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.encoding = new XFAObjectArray();\n  }\n}\nclass Encrypt extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"encrypt\", true);\n    this.id = attributes.id || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.certificate = null;\n  }\n}\nclass EncryptData extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"encryptData\", true);\n    this.id = attributes.id || \"\";\n    this.operation = getStringOption(attributes.operation, [\"encrypt\", \"decrypt\"]);\n    this.target = attributes.target || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.filter = null;\n    this.manifest = null;\n  }\n}\nclass Encryption extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"encryption\", true);\n    this.id = attributes.id || \"\";\n    this.type = getStringOption(attributes.type, [\"optional\", \"required\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.certificate = new XFAObjectArray();\n  }\n}\nclass EncryptionMethod extends OptionObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"encryptionMethod\", [\"\", \"AES256-CBC\", \"TRIPLEDES-CBC\", \"AES128-CBC\", \"AES192-CBC\"]);\n    this.id = attributes.id || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass EncryptionMethods extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"encryptionMethods\", true);\n    this.id = attributes.id || \"\";\n    this.type = getStringOption(attributes.type, [\"optional\", \"required\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.encryptionMethod = new XFAObjectArray();\n  }\n}\nclass Event extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"event\", true);\n    this.activity = getStringOption(attributes.activity, [\"click\", \"change\", \"docClose\", \"docReady\", \"enter\", \"exit\", \"full\", \"indexChange\", \"initialize\", \"mouseDown\", \"mouseEnter\", \"mouseExit\", \"mouseUp\", \"postExecute\", \"postOpen\", \"postPrint\", \"postSave\", \"postSign\", \"postSubmit\", \"preExecute\", \"preOpen\", \"prePrint\", \"preSave\", \"preSign\", \"preSubmit\", \"ready\", \"validationState\"]);\n    this.id = attributes.id || \"\";\n    this.listen = getStringOption(attributes.listen, [\"refOnly\", \"refAndDescendents\"]);\n    this.name = attributes.name || \"\";\n    this.ref = attributes.ref || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.extras = null;\n    this.encryptData = null;\n    this.execute = null;\n    this.script = null;\n    this.signData = null;\n    this.submit = null;\n  }\n}\nclass ExData extends ContentObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"exData\");\n    this.contentType = attributes.contentType || \"\";\n    this.href = attributes.href || \"\";\n    this.id = attributes.id || \"\";\n    this.maxLength = getInteger({\n      data: attributes.maxLength,\n      defaultValue: -1,\n      validate: x => x >= -1\n    });\n    this.name = attributes.name || \"\";\n    this.rid = attributes.rid || \"\";\n    this.transferEncoding = getStringOption(attributes.transferEncoding, [\"none\", \"base64\", \"package\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n  [$isCDATAXml]() {\n    return this.contentType === \"text/html\";\n  }\n  [$onChild](child) {\n    if (this.contentType === \"text/html\" && child[$namespaceId] === NamespaceIds.xhtml.id) {\n      this[$content] = child;\n      return true;\n    }\n    if (this.contentType === \"text/xml\") {\n      this[$content] = child;\n      return true;\n    }\n    return false;\n  }\n  [$toHTML](availableSpace) {\n    if (this.contentType !== \"text/html\" || !this[$content]) {\n      return HTMLResult.EMPTY;\n    }\n    return this[$content][$toHTML](availableSpace);\n  }\n}\nclass ExObject extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"exObject\", true);\n    this.archive = attributes.archive || \"\";\n    this.classId = attributes.classId || \"\";\n    this.codeBase = attributes.codeBase || \"\";\n    this.codeType = attributes.codeType || \"\";\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.extras = null;\n    this.boolean = new XFAObjectArray();\n    this.date = new XFAObjectArray();\n    this.dateTime = new XFAObjectArray();\n    this.decimal = new XFAObjectArray();\n    this.exData = new XFAObjectArray();\n    this.exObject = new XFAObjectArray();\n    this.float = new XFAObjectArray();\n    this.image = new XFAObjectArray();\n    this.integer = new XFAObjectArray();\n    this.text = new XFAObjectArray();\n    this.time = new XFAObjectArray();\n  }\n}\nclass ExclGroup extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"exclGroup\", true);\n    this.access = getStringOption(attributes.access, [\"open\", \"nonInteractive\", \"protected\", \"readOnly\"]);\n    this.accessKey = attributes.accessKey || \"\";\n    this.anchorType = getStringOption(attributes.anchorType, [\"topLeft\", \"bottomCenter\", \"bottomLeft\", \"bottomRight\", \"middleCenter\", \"middleLeft\", \"middleRight\", \"topCenter\", \"topRight\"]);\n    this.colSpan = getInteger({\n      data: attributes.colSpan,\n      defaultValue: 1,\n      validate: n => n >= 1 || n === -1\n    });\n    this.h = attributes.h ? getMeasurement(attributes.h) : \"\";\n    this.hAlign = getStringOption(attributes.hAlign, [\"left\", \"center\", \"justify\", \"justifyAll\", \"radix\", \"right\"]);\n    this.id = attributes.id || \"\";\n    this.layout = getStringOption(attributes.layout, [\"position\", \"lr-tb\", \"rl-row\", \"rl-tb\", \"row\", \"table\", \"tb\"]);\n    this.maxH = getMeasurement(attributes.maxH, \"0pt\");\n    this.maxW = getMeasurement(attributes.maxW, \"0pt\");\n    this.minH = getMeasurement(attributes.minH, \"0pt\");\n    this.minW = getMeasurement(attributes.minW, \"0pt\");\n    this.name = attributes.name || \"\";\n    this.presence = getStringOption(attributes.presence, [\"visible\", \"hidden\", \"inactive\", \"invisible\"]);\n    this.relevant = getRelevant(attributes.relevant);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.w = attributes.w ? getMeasurement(attributes.w) : \"\";\n    this.x = getMeasurement(attributes.x, \"0pt\");\n    this.y = getMeasurement(attributes.y, \"0pt\");\n    this.assist = null;\n    this.bind = null;\n    this.border = null;\n    this.calculate = null;\n    this.caption = null;\n    this.desc = null;\n    this.extras = null;\n    this.margin = null;\n    this.para = null;\n    this.traversal = null;\n    this.validate = null;\n    this.connect = new XFAObjectArray();\n    this.event = new XFAObjectArray();\n    this.field = new XFAObjectArray();\n    this.setProperty = new XFAObjectArray();\n  }\n  [$isBindable]() {\n    return true;\n  }\n  [$hasSettableValue]() {\n    return true;\n  }\n  [$setValue](value) {\n    for (const field of this.field.children) {\n      if (!field.value) {\n        const nodeValue = new Value({});\n        field[$appendChild](nodeValue);\n        field.value = nodeValue;\n      }\n      field.value[$setValue](value);\n    }\n  }\n  [$isThereMoreWidth]() {\n    return this.layout.endsWith(\"-tb\") && this[$extra].attempt === 0 && this[$extra].numberInLine > 0 || this[$getParent]()[$isThereMoreWidth]();\n  }\n  [$isSplittable]() {\n    const parent = this[$getSubformParent]();\n    if (!parent[$isSplittable]()) {\n      return false;\n    }\n    if (this[$extra]._isSplittable !== undefined) {\n      return this[$extra]._isSplittable;\n    }\n    if (this.layout === \"position\" || this.layout.includes(\"row\")) {\n      this[$extra]._isSplittable = false;\n      return false;\n    }\n    if (parent.layout?.endsWith(\"-tb\") && parent[$extra].numberInLine !== 0) {\n      return false;\n    }\n    this[$extra]._isSplittable = true;\n    return true;\n  }\n  [$flushHTML]() {\n    return flushHTML(this);\n  }\n  [$addHTML](html, bbox) {\n    addHTML(this, html, bbox);\n  }\n  [$getAvailableSpace]() {\n    return getAvailableSpace(this);\n  }\n  [$toHTML](availableSpace) {\n    setTabIndex(this);\n    if (this.presence === \"hidden\" || this.presence === \"inactive\" || this.h === 0 || this.w === 0) {\n      return HTMLResult.EMPTY;\n    }\n    fixDimensions(this);\n    const children = [];\n    const attributes = {\n      id: this[$uid],\n      class: []\n    };\n    setAccess(this, attributes.class);\n    if (!this[$extra]) {\n      this[$extra] = Object.create(null);\n    }\n    Object.assign(this[$extra], {\n      children,\n      attributes,\n      attempt: 0,\n      line: null,\n      numberInLine: 0,\n      availableSpace: {\n        width: Math.min(this.w || Infinity, availableSpace.width),\n        height: Math.min(this.h || Infinity, availableSpace.height)\n      },\n      width: 0,\n      height: 0,\n      prevHeight: 0,\n      currentWidth: 0\n    });\n    const isSplittable = this[$isSplittable]();\n    if (!isSplittable) {\n      setFirstUnsplittable(this);\n    }\n    if (!checkDimensions(this, availableSpace)) {\n      return HTMLResult.FAILURE;\n    }\n    const filter = new Set([\"field\"]);\n    if (this.layout.includes(\"row\")) {\n      const columnWidths = this[$getSubformParent]().columnWidths;\n      if (Array.isArray(columnWidths) && columnWidths.length > 0) {\n        this[$extra].columnWidths = columnWidths;\n        this[$extra].currentColumn = 0;\n      }\n    }\n    const style = toStyle(this, \"anchorType\", \"dimensions\", \"position\", \"presence\", \"border\", \"margin\", \"hAlign\");\n    const classNames = [\"xfaExclgroup\"];\n    const cl = layoutClass(this);\n    if (cl) {\n      classNames.push(cl);\n    }\n    if (isPrintOnly(this)) {\n      classNames.push(\"xfaPrintOnly\");\n    }\n    attributes.style = style;\n    attributes.class = classNames;\n    if (this.name) {\n      attributes.xfaName = this.name;\n    }\n    this[$pushPara]();\n    const isLrTb = this.layout === \"lr-tb\" || this.layout === \"rl-tb\";\n    const maxRun = isLrTb ? MAX_ATTEMPTS_FOR_LRTB_LAYOUT : 1;\n    for (; this[$extra].attempt < maxRun; this[$extra].attempt++) {\n      if (isLrTb && this[$extra].attempt === MAX_ATTEMPTS_FOR_LRTB_LAYOUT - 1) {\n        this[$extra].numberInLine = 0;\n      }\n      const result = this[$childrenToHTML]({\n        filter,\n        include: true\n      });\n      if (result.success) {\n        break;\n      }\n      if (result.isBreak()) {\n        this[$popPara]();\n        return result;\n      }\n      if (isLrTb && this[$extra].attempt === 0 && this[$extra].numberInLine === 0 && !this[$getTemplateRoot]()[$extra].noLayoutFailure) {\n        this[$extra].attempt = maxRun;\n        break;\n      }\n    }\n    this[$popPara]();\n    if (!isSplittable) {\n      unsetFirstUnsplittable(this);\n    }\n    if (this[$extra].attempt === maxRun) {\n      if (!isSplittable) {\n        delete this[$extra];\n      }\n      return HTMLResult.FAILURE;\n    }\n    let marginH = 0;\n    let marginV = 0;\n    if (this.margin) {\n      marginH = this.margin.leftInset + this.margin.rightInset;\n      marginV = this.margin.topInset + this.margin.bottomInset;\n    }\n    const width = Math.max(this[$extra].width + marginH, this.w || 0);\n    const height = Math.max(this[$extra].height + marginV, this.h || 0);\n    const bbox = [this.x, this.y, width, height];\n    if (this.w === \"\") {\n      style.width = measureToString(width);\n    }\n    if (this.h === \"\") {\n      style.height = measureToString(height);\n    }\n    const html = {\n      name: \"div\",\n      attributes,\n      children\n    };\n    applyAssist(this, attributes);\n    delete this[$extra];\n    return HTMLResult.success(createWrapper(this, html), bbox);\n  }\n}\nclass Execute extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"execute\");\n    this.connection = attributes.connection || \"\";\n    this.executeType = getStringOption(attributes.executeType, [\"import\", \"remerge\"]);\n    this.id = attributes.id || \"\";\n    this.runAt = getStringOption(attributes.runAt, [\"client\", \"both\", \"server\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass Extras extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"extras\", true);\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.boolean = new XFAObjectArray();\n    this.date = new XFAObjectArray();\n    this.dateTime = new XFAObjectArray();\n    this.decimal = new XFAObjectArray();\n    this.exData = new XFAObjectArray();\n    this.extras = new XFAObjectArray();\n    this.float = new XFAObjectArray();\n    this.image = new XFAObjectArray();\n    this.integer = new XFAObjectArray();\n    this.text = new XFAObjectArray();\n    this.time = new XFAObjectArray();\n  }\n}\nclass Field extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"field\", true);\n    this.access = getStringOption(attributes.access, [\"open\", \"nonInteractive\", \"protected\", \"readOnly\"]);\n    this.accessKey = attributes.accessKey || \"\";\n    this.anchorType = getStringOption(attributes.anchorType, [\"topLeft\", \"bottomCenter\", \"bottomLeft\", \"bottomRight\", \"middleCenter\", \"middleLeft\", \"middleRight\", \"topCenter\", \"topRight\"]);\n    this.colSpan = getInteger({\n      data: attributes.colSpan,\n      defaultValue: 1,\n      validate: n => n >= 1 || n === -1\n    });\n    this.h = attributes.h ? getMeasurement(attributes.h) : \"\";\n    this.hAlign = getStringOption(attributes.hAlign, [\"left\", \"center\", \"justify\", \"justifyAll\", \"radix\", \"right\"]);\n    this.id = attributes.id || \"\";\n    this.locale = attributes.locale || \"\";\n    this.maxH = getMeasurement(attributes.maxH, \"0pt\");\n    this.maxW = getMeasurement(attributes.maxW, \"0pt\");\n    this.minH = getMeasurement(attributes.minH, \"0pt\");\n    this.minW = getMeasurement(attributes.minW, \"0pt\");\n    this.name = attributes.name || \"\";\n    this.presence = getStringOption(attributes.presence, [\"visible\", \"hidden\", \"inactive\", \"invisible\"]);\n    this.relevant = getRelevant(attributes.relevant);\n    this.rotate = getInteger({\n      data: attributes.rotate,\n      defaultValue: 0,\n      validate: x => x % 90 === 0\n    });\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.w = attributes.w ? getMeasurement(attributes.w) : \"\";\n    this.x = getMeasurement(attributes.x, \"0pt\");\n    this.y = getMeasurement(attributes.y, \"0pt\");\n    this.assist = null;\n    this.bind = null;\n    this.border = null;\n    this.calculate = null;\n    this.caption = null;\n    this.desc = null;\n    this.extras = null;\n    this.font = null;\n    this.format = null;\n    this.items = new XFAObjectArray(2);\n    this.keep = null;\n    this.margin = null;\n    this.para = null;\n    this.traversal = null;\n    this.ui = null;\n    this.validate = null;\n    this.value = null;\n    this.bindItems = new XFAObjectArray();\n    this.connect = new XFAObjectArray();\n    this.event = new XFAObjectArray();\n    this.setProperty = new XFAObjectArray();\n  }\n  [$isBindable]() {\n    return true;\n  }\n  [$setValue](value) {\n    _setValue(this, value);\n  }\n  [$toHTML](availableSpace) {\n    setTabIndex(this);\n    if (!this.ui) {\n      this.ui = new Ui({});\n      this.ui[$globalData] = this[$globalData];\n      this[$appendChild](this.ui);\n      let node;\n      switch (this.items.children.length) {\n        case 0:\n          node = new TextEdit({});\n          this.ui.textEdit = node;\n          break;\n        case 1:\n          node = new CheckButton({});\n          this.ui.checkButton = node;\n          break;\n        case 2:\n          node = new ChoiceList({});\n          this.ui.choiceList = node;\n          break;\n      }\n      this.ui[$appendChild](node);\n    }\n    if (!this.ui || this.presence === \"hidden\" || this.presence === \"inactive\" || this.h === 0 || this.w === 0) {\n      return HTMLResult.EMPTY;\n    }\n    if (this.caption) {\n      delete this.caption[$extra];\n    }\n    this[$pushPara]();\n    const caption = this.caption ? this.caption[$toHTML](availableSpace).html : null;\n    const savedW = this.w;\n    const savedH = this.h;\n    let marginH = 0;\n    let marginV = 0;\n    if (this.margin) {\n      marginH = this.margin.leftInset + this.margin.rightInset;\n      marginV = this.margin.topInset + this.margin.bottomInset;\n    }\n    let borderDims = null;\n    if (this.w === \"\" || this.h === \"\") {\n      let width = null;\n      let height = null;\n      let uiW = 0;\n      let uiH = 0;\n      if (this.ui.checkButton) {\n        uiW = uiH = this.ui.checkButton.size;\n      } else {\n        const {\n          w,\n          h\n        } = layoutNode(this, availableSpace);\n        if (w !== null) {\n          uiW = w;\n          uiH = h;\n        } else {\n          uiH = fonts_getMetrics(this.font, true).lineNoGap;\n        }\n      }\n      borderDims = getBorderDims(this.ui[$getExtra]());\n      uiW += borderDims.w;\n      uiH += borderDims.h;\n      if (this.caption) {\n        const {\n          w,\n          h,\n          isBroken\n        } = this.caption[$getExtra](availableSpace);\n        if (isBroken && this[$getSubformParent]()[$isThereMoreWidth]()) {\n          this[$popPara]();\n          return HTMLResult.FAILURE;\n        }\n        width = w;\n        height = h;\n        switch (this.caption.placement) {\n          case \"left\":\n          case \"right\":\n          case \"inline\":\n            width += uiW;\n            break;\n          case \"top\":\n          case \"bottom\":\n            height += uiH;\n            break;\n        }\n      } else {\n        width = uiW;\n        height = uiH;\n      }\n      if (width && this.w === \"\") {\n        width += marginH;\n        this.w = Math.min(this.maxW <= 0 ? Infinity : this.maxW, this.minW + 1 < width ? width : this.minW);\n      }\n      if (height && this.h === \"\") {\n        height += marginV;\n        this.h = Math.min(this.maxH <= 0 ? Infinity : this.maxH, this.minH + 1 < height ? height : this.minH);\n      }\n    }\n    this[$popPara]();\n    fixDimensions(this);\n    setFirstUnsplittable(this);\n    if (!checkDimensions(this, availableSpace)) {\n      this.w = savedW;\n      this.h = savedH;\n      this[$popPara]();\n      return HTMLResult.FAILURE;\n    }\n    unsetFirstUnsplittable(this);\n    const style = toStyle(this, \"font\", \"dimensions\", \"position\", \"rotate\", \"anchorType\", \"presence\", \"margin\", \"hAlign\");\n    setMinMaxDimensions(this, style);\n    const classNames = [\"xfaField\"];\n    if (this.font) {\n      classNames.push(\"xfaFont\");\n    }\n    if (isPrintOnly(this)) {\n      classNames.push(\"xfaPrintOnly\");\n    }\n    const attributes = {\n      style,\n      id: this[$uid],\n      class: classNames\n    };\n    if (style.margin) {\n      style.padding = style.margin;\n      delete style.margin;\n    }\n    setAccess(this, classNames);\n    if (this.name) {\n      attributes.xfaName = this.name;\n    }\n    const children = [];\n    const html = {\n      name: \"div\",\n      attributes,\n      children\n    };\n    applyAssist(this, attributes);\n    const borderStyle = this.border ? this.border[$toStyle]() : null;\n    const bbox = computeBbox(this, html, availableSpace);\n    const ui = this.ui[$toHTML]().html;\n    if (!ui) {\n      Object.assign(style, borderStyle);\n      return HTMLResult.success(createWrapper(this, html), bbox);\n    }\n    if (this[$tabIndex]) {\n      if (ui.children?.[0]) {\n        ui.children[0].attributes.tabindex = this[$tabIndex];\n      } else {\n        ui.attributes.tabindex = this[$tabIndex];\n      }\n    }\n    if (!ui.attributes.style) {\n      ui.attributes.style = Object.create(null);\n    }\n    let aElement = null;\n    if (this.ui.button) {\n      if (ui.children.length === 1) {\n        [aElement] = ui.children.splice(0, 1);\n      }\n      Object.assign(ui.attributes.style, borderStyle);\n    } else {\n      Object.assign(style, borderStyle);\n    }\n    children.push(ui);\n    if (this.value) {\n      if (this.ui.imageEdit) {\n        ui.children.push(this.value[$toHTML]().html);\n      } else if (!this.ui.button) {\n        let value = \"\";\n        if (this.value.exData) {\n          value = this.value.exData[$text]();\n        } else if (this.value.text) {\n          value = this.value.text[$getExtra]();\n        } else {\n          const htmlValue = this.value[$toHTML]().html;\n          if (htmlValue !== null) {\n            value = htmlValue.children[0].value;\n          }\n        }\n        if (this.ui.textEdit && this.value.text?.maxChars) {\n          ui.children[0].attributes.maxLength = this.value.text.maxChars;\n        }\n        if (value) {\n          if (this.ui.numericEdit) {\n            value = parseFloat(value);\n            value = isNaN(value) ? \"\" : value.toString();\n          }\n          if (ui.children[0].name === \"textarea\") {\n            ui.children[0].attributes.textContent = value;\n          } else {\n            ui.children[0].attributes.value = value;\n          }\n        }\n      }\n    }\n    if (!this.ui.imageEdit && ui.children?.[0] && this.h) {\n      borderDims = borderDims || getBorderDims(this.ui[$getExtra]());\n      let captionHeight = 0;\n      if (this.caption && [\"top\", \"bottom\"].includes(this.caption.placement)) {\n        captionHeight = this.caption.reserve;\n        if (captionHeight <= 0) {\n          captionHeight = this.caption[$getExtra](availableSpace).h;\n        }\n        const inputHeight = this.h - captionHeight - marginV - borderDims.h;\n        ui.children[0].attributes.style.height = measureToString(inputHeight);\n      } else {\n        ui.children[0].attributes.style.height = \"100%\";\n      }\n    }\n    if (aElement) {\n      ui.children.push(aElement);\n    }\n    if (!caption) {\n      if (ui.attributes.class) {\n        ui.attributes.class.push(\"xfaLeft\");\n      }\n      this.w = savedW;\n      this.h = savedH;\n      return HTMLResult.success(createWrapper(this, html), bbox);\n    }\n    if (this.ui.button) {\n      if (style.padding) {\n        delete style.padding;\n      }\n      if (caption.name === \"div\") {\n        caption.name = \"span\";\n      }\n      ui.children.push(caption);\n      return HTMLResult.success(html, bbox);\n    } else if (this.ui.checkButton) {\n      caption.attributes.class[0] = \"xfaCaptionForCheckButton\";\n    }\n    if (!ui.attributes.class) {\n      ui.attributes.class = [];\n    }\n    ui.children.splice(0, 0, caption);\n    switch (this.caption.placement) {\n      case \"left\":\n        ui.attributes.class.push(\"xfaLeft\");\n        break;\n      case \"right\":\n        ui.attributes.class.push(\"xfaRight\");\n        break;\n      case \"top\":\n        ui.attributes.class.push(\"xfaTop\");\n        break;\n      case \"bottom\":\n        ui.attributes.class.push(\"xfaBottom\");\n        break;\n      case \"inline\":\n        ui.attributes.class.push(\"xfaLeft\");\n        break;\n    }\n    this.w = savedW;\n    this.h = savedH;\n    return HTMLResult.success(createWrapper(this, html), bbox);\n  }\n}\nclass Fill extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"fill\", true);\n    this.id = attributes.id || \"\";\n    this.presence = getStringOption(attributes.presence, [\"visible\", \"hidden\", \"inactive\", \"invisible\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.color = null;\n    this.extras = null;\n    this.linear = null;\n    this.pattern = null;\n    this.radial = null;\n    this.solid = null;\n    this.stipple = null;\n  }\n  [$toStyle]() {\n    const parent = this[$getParent]();\n    const grandpa = parent[$getParent]();\n    const ggrandpa = grandpa[$getParent]();\n    const style = Object.create(null);\n    let propName = \"color\";\n    let altPropName = propName;\n    if (parent instanceof Border) {\n      propName = \"background-color\";\n      altPropName = \"background\";\n      if (ggrandpa instanceof Ui) {\n        style.backgroundColor = \"white\";\n      }\n    }\n    if (parent instanceof Rectangle || parent instanceof Arc) {\n      propName = altPropName = \"fill\";\n      style.fill = \"white\";\n    }\n    for (const name of Object.getOwnPropertyNames(this)) {\n      if (name === \"extras\" || name === \"color\") {\n        continue;\n      }\n      const obj = this[name];\n      if (!(obj instanceof XFAObject)) {\n        continue;\n      }\n      const color = obj[$toStyle](this.color);\n      if (color) {\n        style[color.startsWith(\"#\") ? propName : altPropName] = color;\n      }\n      return style;\n    }\n    if (this.color?.value) {\n      const color = this.color[$toStyle]();\n      style[color.startsWith(\"#\") ? propName : altPropName] = color;\n    }\n    return style;\n  }\n}\nclass Filter extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"filter\", true);\n    this.addRevocationInfo = getStringOption(attributes.addRevocationInfo, [\"\", \"required\", \"optional\", \"none\"]);\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.version = getInteger({\n      data: this.version,\n      defaultValue: 5,\n      validate: x => x >= 1 && x <= 5\n    });\n    this.appearanceFilter = null;\n    this.certificates = null;\n    this.digestMethods = null;\n    this.encodings = null;\n    this.encryptionMethods = null;\n    this.handler = null;\n    this.lockDocument = null;\n    this.mdp = null;\n    this.reasons = null;\n    this.timeStamp = null;\n  }\n}\nclass Float extends ContentObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"float\");\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n  [$finalize]() {\n    const number = parseFloat(this[$content].trim());\n    this[$content] = isNaN(number) ? null : number;\n  }\n  [$toHTML](availableSpace) {\n    return valueToHtml(this[$content] !== null ? this[$content].toString() : \"\");\n  }\n}\nclass template_Font extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"font\", true);\n    this.baselineShift = getMeasurement(attributes.baselineShift);\n    this.fontHorizontalScale = getFloat({\n      data: attributes.fontHorizontalScale,\n      defaultValue: 100,\n      validate: x => x >= 0\n    });\n    this.fontVerticalScale = getFloat({\n      data: attributes.fontVerticalScale,\n      defaultValue: 100,\n      validate: x => x >= 0\n    });\n    this.id = attributes.id || \"\";\n    this.kerningMode = getStringOption(attributes.kerningMode, [\"none\", \"pair\"]);\n    this.letterSpacing = getMeasurement(attributes.letterSpacing, \"0\");\n    this.lineThrough = getInteger({\n      data: attributes.lineThrough,\n      defaultValue: 0,\n      validate: x => x === 1 || x === 2\n    });\n    this.lineThroughPeriod = getStringOption(attributes.lineThroughPeriod, [\"all\", \"word\"]);\n    this.overline = getInteger({\n      data: attributes.overline,\n      defaultValue: 0,\n      validate: x => x === 1 || x === 2\n    });\n    this.overlinePeriod = getStringOption(attributes.overlinePeriod, [\"all\", \"word\"]);\n    this.posture = getStringOption(attributes.posture, [\"normal\", \"italic\"]);\n    this.size = getMeasurement(attributes.size, \"10pt\");\n    this.typeface = attributes.typeface || \"Courier\";\n    this.underline = getInteger({\n      data: attributes.underline,\n      defaultValue: 0,\n      validate: x => x === 1 || x === 2\n    });\n    this.underlinePeriod = getStringOption(attributes.underlinePeriod, [\"all\", \"word\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.weight = getStringOption(attributes.weight, [\"normal\", \"bold\"]);\n    this.extras = null;\n    this.fill = null;\n  }\n  [$clean](builder) {\n    super[$clean](builder);\n    this[$globalData].usedTypefaces.add(this.typeface);\n  }\n  [$toStyle]() {\n    const style = toStyle(this, \"fill\");\n    const color = style.color;\n    if (color) {\n      if (color === \"#000000\") {\n        delete style.color;\n      } else if (!color.startsWith(\"#\")) {\n        style.background = color;\n        style.backgroundClip = \"text\";\n        style.color = \"transparent\";\n      }\n    }\n    if (this.baselineShift) {\n      style.verticalAlign = measureToString(this.baselineShift);\n    }\n    style.fontKerning = this.kerningMode === \"none\" ? \"none\" : \"normal\";\n    style.letterSpacing = measureToString(this.letterSpacing);\n    if (this.lineThrough !== 0) {\n      style.textDecoration = \"line-through\";\n      if (this.lineThrough === 2) {\n        style.textDecorationStyle = \"double\";\n      }\n    }\n    if (this.overline !== 0) {\n      style.textDecoration = \"overline\";\n      if (this.overline === 2) {\n        style.textDecorationStyle = \"double\";\n      }\n    }\n    style.fontStyle = this.posture;\n    style.fontSize = measureToString(0.99 * this.size);\n    setFontFamily(this, this, this[$globalData].fontFinder, style);\n    if (this.underline !== 0) {\n      style.textDecoration = \"underline\";\n      if (this.underline === 2) {\n        style.textDecorationStyle = \"double\";\n      }\n    }\n    style.fontWeight = this.weight;\n    return style;\n  }\n}\nclass Format extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"format\", true);\n    this.id = attributes.id || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.extras = null;\n    this.picture = null;\n  }\n}\nclass Handler extends StringObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"handler\");\n    this.id = attributes.id || \"\";\n    this.type = getStringOption(attributes.type, [\"optional\", \"required\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass Hyphenation extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"hyphenation\");\n    this.excludeAllCaps = getInteger({\n      data: attributes.excludeAllCaps,\n      defaultValue: 0,\n      validate: x => x === 1\n    });\n    this.excludeInitialCap = getInteger({\n      data: attributes.excludeInitialCap,\n      defaultValue: 0,\n      validate: x => x === 1\n    });\n    this.hyphenate = getInteger({\n      data: attributes.hyphenate,\n      defaultValue: 0,\n      validate: x => x === 1\n    });\n    this.id = attributes.id || \"\";\n    this.pushCharacterCount = getInteger({\n      data: attributes.pushCharacterCount,\n      defaultValue: 3,\n      validate: x => x >= 0\n    });\n    this.remainCharacterCount = getInteger({\n      data: attributes.remainCharacterCount,\n      defaultValue: 3,\n      validate: x => x >= 0\n    });\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.wordCharacterCount = getInteger({\n      data: attributes.wordCharacterCount,\n      defaultValue: 7,\n      validate: x => x >= 0\n    });\n  }\n}\nclass Image extends StringObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"image\");\n    this.aspect = getStringOption(attributes.aspect, [\"fit\", \"actual\", \"height\", \"none\", \"width\"]);\n    this.contentType = attributes.contentType || \"\";\n    this.href = attributes.href || \"\";\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.transferEncoding = getStringOption(attributes.transferEncoding, [\"base64\", \"none\", \"package\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n  [$toHTML]() {\n    if (this.contentType && !MIMES.has(this.contentType.toLowerCase())) {\n      return HTMLResult.EMPTY;\n    }\n    let buffer = this[$globalData].images && this[$globalData].images.get(this.href);\n    if (!buffer && (this.href || !this[$content])) {\n      return HTMLResult.EMPTY;\n    }\n    if (!buffer && this.transferEncoding === \"base64\") {\n      buffer = stringToBytes(atob(this[$content]));\n    }\n    if (!buffer) {\n      return HTMLResult.EMPTY;\n    }\n    if (!this.contentType) {\n      for (const [header, type] of IMAGES_HEADERS) {\n        if (buffer.length > header.length && header.every((x, i) => x === buffer[i])) {\n          this.contentType = type;\n          break;\n        }\n      }\n      if (!this.contentType) {\n        return HTMLResult.EMPTY;\n      }\n    }\n    const blob = new Blob([buffer], {\n      type: this.contentType\n    });\n    let style;\n    switch (this.aspect) {\n      case \"fit\":\n      case \"actual\":\n        break;\n      case \"height\":\n        style = {\n          height: \"100%\",\n          objectFit: \"fill\"\n        };\n        break;\n      case \"none\":\n        style = {\n          width: \"100%\",\n          height: \"100%\",\n          objectFit: \"fill\"\n        };\n        break;\n      case \"width\":\n        style = {\n          width: \"100%\",\n          objectFit: \"fill\"\n        };\n        break;\n    }\n    const parent = this[$getParent]();\n    return HTMLResult.success({\n      name: \"img\",\n      attributes: {\n        class: [\"xfaImage\"],\n        style,\n        src: URL.createObjectURL(blob),\n        alt: parent ? ariaLabel(parent[$getParent]()) : null\n      }\n    });\n  }\n}\nclass ImageEdit extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"imageEdit\", true);\n    this.data = getStringOption(attributes.data, [\"link\", \"embed\"]);\n    this.id = attributes.id || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.border = null;\n    this.extras = null;\n    this.margin = null;\n  }\n  [$toHTML](availableSpace) {\n    if (this.data === \"embed\") {\n      return HTMLResult.success({\n        name: \"div\",\n        children: [],\n        attributes: {}\n      });\n    }\n    return HTMLResult.EMPTY;\n  }\n}\nclass Integer extends ContentObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"integer\");\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n  [$finalize]() {\n    const number = parseInt(this[$content].trim(), 10);\n    this[$content] = isNaN(number) ? null : number;\n  }\n  [$toHTML](availableSpace) {\n    return valueToHtml(this[$content] !== null ? this[$content].toString() : \"\");\n  }\n}\nclass Issuers extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"issuers\", true);\n    this.id = attributes.id || \"\";\n    this.type = getStringOption(attributes.type, [\"optional\", \"required\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.certificate = new XFAObjectArray();\n  }\n}\nclass Items extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"items\", true);\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.presence = getStringOption(attributes.presence, [\"visible\", \"hidden\", \"inactive\", \"invisible\"]);\n    this.ref = attributes.ref || \"\";\n    this.save = getInteger({\n      data: attributes.save,\n      defaultValue: 0,\n      validate: x => x === 1\n    });\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.boolean = new XFAObjectArray();\n    this.date = new XFAObjectArray();\n    this.dateTime = new XFAObjectArray();\n    this.decimal = new XFAObjectArray();\n    this.exData = new XFAObjectArray();\n    this.float = new XFAObjectArray();\n    this.image = new XFAObjectArray();\n    this.integer = new XFAObjectArray();\n    this.text = new XFAObjectArray();\n    this.time = new XFAObjectArray();\n  }\n  [$toHTML]() {\n    const output = [];\n    for (const child of this[$getChildren]()) {\n      output.push(child[$text]());\n    }\n    return HTMLResult.success(output);\n  }\n}\nclass Keep extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"keep\", true);\n    this.id = attributes.id || \"\";\n    const options = [\"none\", \"contentArea\", \"pageArea\"];\n    this.intact = getStringOption(attributes.intact, options);\n    this.next = getStringOption(attributes.next, options);\n    this.previous = getStringOption(attributes.previous, options);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.extras = null;\n  }\n}\nclass KeyUsage extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"keyUsage\");\n    const options = [\"\", \"yes\", \"no\"];\n    this.crlSign = getStringOption(attributes.crlSign, options);\n    this.dataEncipherment = getStringOption(attributes.dataEncipherment, options);\n    this.decipherOnly = getStringOption(attributes.decipherOnly, options);\n    this.digitalSignature = getStringOption(attributes.digitalSignature, options);\n    this.encipherOnly = getStringOption(attributes.encipherOnly, options);\n    this.id = attributes.id || \"\";\n    this.keyAgreement = getStringOption(attributes.keyAgreement, options);\n    this.keyCertSign = getStringOption(attributes.keyCertSign, options);\n    this.keyEncipherment = getStringOption(attributes.keyEncipherment, options);\n    this.nonRepudiation = getStringOption(attributes.nonRepudiation, options);\n    this.type = getStringOption(attributes.type, [\"optional\", \"required\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass Line extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"line\", true);\n    this.hand = getStringOption(attributes.hand, [\"even\", \"left\", \"right\"]);\n    this.id = attributes.id || \"\";\n    this.slope = getStringOption(attributes.slope, [\"\\\\\", \"/\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.edge = null;\n  }\n  [$toHTML]() {\n    const parent = this[$getParent]()[$getParent]();\n    const edge = this.edge || new Edge({});\n    const edgeStyle = edge[$toStyle]();\n    const style = Object.create(null);\n    const thickness = edge.presence === \"visible\" ? edge.thickness : 0;\n    style.strokeWidth = measureToString(thickness);\n    style.stroke = edgeStyle.color;\n    let x1, y1, x2, y2;\n    let width = \"100%\";\n    let height = \"100%\";\n    if (parent.w <= thickness) {\n      [x1, y1, x2, y2] = [\"50%\", 0, \"50%\", \"100%\"];\n      width = style.strokeWidth;\n    } else if (parent.h <= thickness) {\n      [x1, y1, x2, y2] = [0, \"50%\", \"100%\", \"50%\"];\n      height = style.strokeWidth;\n    } else if (this.slope === \"\\\\\") {\n      [x1, y1, x2, y2] = [0, 0, \"100%\", \"100%\"];\n    } else {\n      [x1, y1, x2, y2] = [0, \"100%\", \"100%\", 0];\n    }\n    const line = {\n      name: \"line\",\n      attributes: {\n        xmlns: SVG_NS,\n        x1,\n        y1,\n        x2,\n        y2,\n        style\n      }\n    };\n    const svg = {\n      name: \"svg\",\n      children: [line],\n      attributes: {\n        xmlns: SVG_NS,\n        width,\n        height,\n        style: {\n          overflow: \"visible\"\n        }\n      }\n    };\n    if (hasMargin(parent)) {\n      return HTMLResult.success({\n        name: \"div\",\n        attributes: {\n          style: {\n            display: \"inline\",\n            width: \"100%\",\n            height: \"100%\"\n          }\n        },\n        children: [svg]\n      });\n    }\n    svg.attributes.style.position = \"absolute\";\n    return HTMLResult.success(svg);\n  }\n}\nclass Linear extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"linear\", true);\n    this.id = attributes.id || \"\";\n    this.type = getStringOption(attributes.type, [\"toRight\", \"toBottom\", \"toLeft\", \"toTop\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.color = null;\n    this.extras = null;\n  }\n  [$toStyle](startColor) {\n    startColor = startColor ? startColor[$toStyle]() : \"#FFFFFF\";\n    const transf = this.type.replace(/([RBLT])/, \" $1\").toLowerCase();\n    const endColor = this.color ? this.color[$toStyle]() : \"#000000\";\n    return `linear-gradient(${transf}, ${startColor}, ${endColor})`;\n  }\n}\nclass LockDocument extends ContentObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"lockDocument\");\n    this.id = attributes.id || \"\";\n    this.type = getStringOption(attributes.type, [\"optional\", \"required\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n  [$finalize]() {\n    this[$content] = getStringOption(this[$content], [\"auto\", \"0\", \"1\"]);\n  }\n}\nclass Manifest extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"manifest\", true);\n    this.action = getStringOption(attributes.action, [\"include\", \"all\", \"exclude\"]);\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.extras = null;\n    this.ref = new XFAObjectArray();\n  }\n}\nclass Margin extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"margin\", true);\n    this.bottomInset = getMeasurement(attributes.bottomInset, \"0\");\n    this.id = attributes.id || \"\";\n    this.leftInset = getMeasurement(attributes.leftInset, \"0\");\n    this.rightInset = getMeasurement(attributes.rightInset, \"0\");\n    this.topInset = getMeasurement(attributes.topInset, \"0\");\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.extras = null;\n  }\n  [$toStyle]() {\n    return {\n      margin: measureToString(this.topInset) + \" \" + measureToString(this.rightInset) + \" \" + measureToString(this.bottomInset) + \" \" + measureToString(this.leftInset)\n    };\n  }\n}\nclass Mdp extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"mdp\");\n    this.id = attributes.id || \"\";\n    this.permissions = 2;\n    this.signatureType = getStringOption(attributes.signatureType, [\"filler\", \"author\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass Medium extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"medium\");\n    this.id = attributes.id || \"\";\n    this.imagingBBox = getBBox(attributes.imagingBBox);\n    this.long = getMeasurement(attributes.long);\n    this.orientation = getStringOption(attributes.orientation, [\"portrait\", \"landscape\"]);\n    this.short = getMeasurement(attributes.short);\n    this.stock = attributes.stock || \"\";\n    this.trayIn = getStringOption(attributes.trayIn, [\"auto\", \"delegate\", \"pageFront\"]);\n    this.trayOut = getStringOption(attributes.trayOut, [\"auto\", \"delegate\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass Message extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"message\", true);\n    this.id = attributes.id || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.text = new XFAObjectArray();\n  }\n}\nclass NumericEdit extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"numericEdit\", true);\n    this.hScrollPolicy = getStringOption(attributes.hScrollPolicy, [\"auto\", \"off\", \"on\"]);\n    this.id = attributes.id || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.border = null;\n    this.comb = null;\n    this.extras = null;\n    this.margin = null;\n  }\n  [$toHTML](availableSpace) {\n    const style = toStyle(this, \"border\", \"font\", \"margin\");\n    const field = this[$getParent]()[$getParent]();\n    const html = {\n      name: \"input\",\n      attributes: {\n        type: \"text\",\n        fieldId: field[$uid],\n        dataId: field[$data]?.[$uid] || field[$uid],\n        class: [\"xfaTextfield\"],\n        style,\n        \"aria-label\": ariaLabel(field),\n        \"aria-required\": false\n      }\n    };\n    if (isRequired(field)) {\n      html.attributes[\"aria-required\"] = true;\n      html.attributes.required = true;\n    }\n    return HTMLResult.success({\n      name: \"label\",\n      attributes: {\n        class: [\"xfaLabel\"]\n      },\n      children: [html]\n    });\n  }\n}\nclass Occur extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"occur\", true);\n    this.id = attributes.id || \"\";\n    this.initial = attributes.initial !== \"\" ? getInteger({\n      data: attributes.initial,\n      defaultValue: \"\",\n      validate: x => true\n    }) : \"\";\n    this.max = attributes.max !== \"\" ? getInteger({\n      data: attributes.max,\n      defaultValue: 1,\n      validate: x => true\n    }) : \"\";\n    this.min = attributes.min !== \"\" ? getInteger({\n      data: attributes.min,\n      defaultValue: 1,\n      validate: x => true\n    }) : \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.extras = null;\n  }\n  [$clean]() {\n    const parent = this[$getParent]();\n    const originalMin = this.min;\n    if (this.min === \"\") {\n      this.min = parent instanceof PageArea || parent instanceof PageSet ? 0 : 1;\n    }\n    if (this.max === \"\") {\n      if (originalMin === \"\") {\n        this.max = parent instanceof PageArea || parent instanceof PageSet ? -1 : 1;\n      } else {\n        this.max = this.min;\n      }\n    }\n    if (this.max !== -1 && this.max < this.min) {\n      this.max = this.min;\n    }\n    if (this.initial === \"\") {\n      this.initial = parent instanceof Template ? 1 : this.min;\n    }\n  }\n}\nclass Oid extends StringObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"oid\");\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass Oids extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"oids\", true);\n    this.id = attributes.id || \"\";\n    this.type = getStringOption(attributes.type, [\"optional\", \"required\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.oid = new XFAObjectArray();\n  }\n}\nclass Overflow extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"overflow\");\n    this.id = attributes.id || \"\";\n    this.leader = attributes.leader || \"\";\n    this.target = attributes.target || \"\";\n    this.trailer = attributes.trailer || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n  [$getExtra]() {\n    if (!this[$extra]) {\n      const parent = this[$getParent]();\n      const root = this[$getTemplateRoot]();\n      const target = root[$searchNode](this.target, parent);\n      const leader = root[$searchNode](this.leader, parent);\n      const trailer = root[$searchNode](this.trailer, parent);\n      this[$extra] = {\n        target: target?.[0] || null,\n        leader: leader?.[0] || null,\n        trailer: trailer?.[0] || null,\n        addLeader: false,\n        addTrailer: false\n      };\n    }\n    return this[$extra];\n  }\n}\nclass PageArea extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"pageArea\", true);\n    this.blankOrNotBlank = getStringOption(attributes.blankOrNotBlank, [\"any\", \"blank\", \"notBlank\"]);\n    this.id = attributes.id || \"\";\n    this.initialNumber = getInteger({\n      data: attributes.initialNumber,\n      defaultValue: 1,\n      validate: x => true\n    });\n    this.name = attributes.name || \"\";\n    this.numbered = getInteger({\n      data: attributes.numbered,\n      defaultValue: 1,\n      validate: x => true\n    });\n    this.oddOrEven = getStringOption(attributes.oddOrEven, [\"any\", \"even\", \"odd\"]);\n    this.pagePosition = getStringOption(attributes.pagePosition, [\"any\", \"first\", \"last\", \"only\", \"rest\"]);\n    this.relevant = getRelevant(attributes.relevant);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.desc = null;\n    this.extras = null;\n    this.medium = null;\n    this.occur = null;\n    this.area = new XFAObjectArray();\n    this.contentArea = new XFAObjectArray();\n    this.draw = new XFAObjectArray();\n    this.exclGroup = new XFAObjectArray();\n    this.field = new XFAObjectArray();\n    this.subform = new XFAObjectArray();\n  }\n  [$isUsable]() {\n    if (!this[$extra]) {\n      this[$extra] = {\n        numberOfUse: 0\n      };\n      return true;\n    }\n    return !this.occur || this.occur.max === -1 || this[$extra].numberOfUse < this.occur.max;\n  }\n  [$cleanPage]() {\n    delete this[$extra];\n  }\n  [$getNextPage]() {\n    if (!this[$extra]) {\n      this[$extra] = {\n        numberOfUse: 0\n      };\n    }\n    const parent = this[$getParent]();\n    if (parent.relation === \"orderedOccurrence\") {\n      if (this[$isUsable]()) {\n        this[$extra].numberOfUse += 1;\n        return this;\n      }\n    }\n    return parent[$getNextPage]();\n  }\n  [$getAvailableSpace]() {\n    return this[$extra].space || {\n      width: 0,\n      height: 0\n    };\n  }\n  [$toHTML]() {\n    if (!this[$extra]) {\n      this[$extra] = {\n        numberOfUse: 1\n      };\n    }\n    const children = [];\n    this[$extra].children = children;\n    const style = Object.create(null);\n    if (this.medium && this.medium.short && this.medium.long) {\n      style.width = measureToString(this.medium.short);\n      style.height = measureToString(this.medium.long);\n      this[$extra].space = {\n        width: this.medium.short,\n        height: this.medium.long\n      };\n      if (this.medium.orientation === \"landscape\") {\n        const x = style.width;\n        style.width = style.height;\n        style.height = x;\n        this[$extra].space = {\n          width: this.medium.long,\n          height: this.medium.short\n        };\n      }\n    } else {\n      warn(\"XFA - No medium specified in pageArea: please file a bug.\");\n    }\n    this[$childrenToHTML]({\n      filter: new Set([\"area\", \"draw\", \"field\", \"subform\"]),\n      include: true\n    });\n    this[$childrenToHTML]({\n      filter: new Set([\"contentArea\"]),\n      include: true\n    });\n    return HTMLResult.success({\n      name: \"div\",\n      children,\n      attributes: {\n        class: [\"xfaPage\"],\n        id: this[$uid],\n        style,\n        xfaName: this.name\n      }\n    });\n  }\n}\nclass PageSet extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"pageSet\", true);\n    this.duplexImposition = getStringOption(attributes.duplexImposition, [\"longEdge\", \"shortEdge\"]);\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.relation = getStringOption(attributes.relation, [\"orderedOccurrence\", \"duplexPaginated\", \"simplexPaginated\"]);\n    this.relevant = getRelevant(attributes.relevant);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.extras = null;\n    this.occur = null;\n    this.pageArea = new XFAObjectArray();\n    this.pageSet = new XFAObjectArray();\n  }\n  [$cleanPage]() {\n    for (const page of this.pageArea.children) {\n      page[$cleanPage]();\n    }\n    for (const page of this.pageSet.children) {\n      page[$cleanPage]();\n    }\n  }\n  [$isUsable]() {\n    return !this.occur || this.occur.max === -1 || this[$extra].numberOfUse < this.occur.max;\n  }\n  [$getNextPage]() {\n    if (!this[$extra]) {\n      this[$extra] = {\n        numberOfUse: 1,\n        pageIndex: -1,\n        pageSetIndex: -1\n      };\n    }\n    if (this.relation === \"orderedOccurrence\") {\n      if (this[$extra].pageIndex + 1 < this.pageArea.children.length) {\n        this[$extra].pageIndex += 1;\n        const pageArea = this.pageArea.children[this[$extra].pageIndex];\n        return pageArea[$getNextPage]();\n      }\n      if (this[$extra].pageSetIndex + 1 < this.pageSet.children.length) {\n        this[$extra].pageSetIndex += 1;\n        return this.pageSet.children[this[$extra].pageSetIndex][$getNextPage]();\n      }\n      if (this[$isUsable]()) {\n        this[$extra].numberOfUse += 1;\n        this[$extra].pageIndex = -1;\n        this[$extra].pageSetIndex = -1;\n        return this[$getNextPage]();\n      }\n      const parent = this[$getParent]();\n      if (parent instanceof PageSet) {\n        return parent[$getNextPage]();\n      }\n      this[$cleanPage]();\n      return this[$getNextPage]();\n    }\n    const pageNumber = this[$getTemplateRoot]()[$extra].pageNumber;\n    const parity = pageNumber % 2 === 0 ? \"even\" : \"odd\";\n    const position = pageNumber === 0 ? \"first\" : \"rest\";\n    let page = this.pageArea.children.find(p => p.oddOrEven === parity && p.pagePosition === position);\n    if (page) {\n      return page;\n    }\n    page = this.pageArea.children.find(p => p.oddOrEven === \"any\" && p.pagePosition === position);\n    if (page) {\n      return page;\n    }\n    page = this.pageArea.children.find(p => p.oddOrEven === \"any\" && p.pagePosition === \"any\");\n    if (page) {\n      return page;\n    }\n    return this.pageArea.children[0];\n  }\n}\nclass Para extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"para\", true);\n    this.hAlign = getStringOption(attributes.hAlign, [\"left\", \"center\", \"justify\", \"justifyAll\", \"radix\", \"right\"]);\n    this.id = attributes.id || \"\";\n    this.lineHeight = attributes.lineHeight ? getMeasurement(attributes.lineHeight, \"0pt\") : \"\";\n    this.marginLeft = attributes.marginLeft ? getMeasurement(attributes.marginLeft, \"0pt\") : \"\";\n    this.marginRight = attributes.marginRight ? getMeasurement(attributes.marginRight, \"0pt\") : \"\";\n    this.orphans = getInteger({\n      data: attributes.orphans,\n      defaultValue: 0,\n      validate: x => x >= 0\n    });\n    this.preserve = attributes.preserve || \"\";\n    this.radixOffset = attributes.radixOffset ? getMeasurement(attributes.radixOffset, \"0pt\") : \"\";\n    this.spaceAbove = attributes.spaceAbove ? getMeasurement(attributes.spaceAbove, \"0pt\") : \"\";\n    this.spaceBelow = attributes.spaceBelow ? getMeasurement(attributes.spaceBelow, \"0pt\") : \"\";\n    this.tabDefault = attributes.tabDefault ? getMeasurement(this.tabDefault) : \"\";\n    this.tabStops = (attributes.tabStops || \"\").trim().split(/\\s+/).map((x, i) => i % 2 === 1 ? getMeasurement(x) : x);\n    this.textIndent = attributes.textIndent ? getMeasurement(attributes.textIndent, \"0pt\") : \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.vAlign = getStringOption(attributes.vAlign, [\"top\", \"bottom\", \"middle\"]);\n    this.widows = getInteger({\n      data: attributes.widows,\n      defaultValue: 0,\n      validate: x => x >= 0\n    });\n    this.hyphenation = null;\n  }\n  [$toStyle]() {\n    const style = toStyle(this, \"hAlign\");\n    if (this.marginLeft !== \"\") {\n      style.paddingLeft = measureToString(this.marginLeft);\n    }\n    if (this.marginRight !== \"\") {\n      style.paddingight = measureToString(this.marginRight);\n    }\n    if (this.spaceAbove !== \"\") {\n      style.paddingTop = measureToString(this.spaceAbove);\n    }\n    if (this.spaceBelow !== \"\") {\n      style.paddingBottom = measureToString(this.spaceBelow);\n    }\n    if (this.textIndent !== \"\") {\n      style.textIndent = measureToString(this.textIndent);\n      fixTextIndent(style);\n    }\n    if (this.lineHeight > 0) {\n      style.lineHeight = measureToString(this.lineHeight);\n    }\n    if (this.tabDefault !== \"\") {\n      style.tabSize = measureToString(this.tabDefault);\n    }\n    if (this.tabStops.length > 0) {}\n    if (this.hyphenatation) {\n      Object.assign(style, this.hyphenatation[$toStyle]());\n    }\n    return style;\n  }\n}\nclass PasswordEdit extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"passwordEdit\", true);\n    this.hScrollPolicy = getStringOption(attributes.hScrollPolicy, [\"auto\", \"off\", \"on\"]);\n    this.id = attributes.id || \"\";\n    this.passwordChar = attributes.passwordChar || \"*\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.border = null;\n    this.extras = null;\n    this.margin = null;\n  }\n}\nclass template_Pattern extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"pattern\", true);\n    this.id = attributes.id || \"\";\n    this.type = getStringOption(attributes.type, [\"crossHatch\", \"crossDiagonal\", \"diagonalLeft\", \"diagonalRight\", \"horizontal\", \"vertical\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.color = null;\n    this.extras = null;\n  }\n  [$toStyle](startColor) {\n    startColor = startColor ? startColor[$toStyle]() : \"#FFFFFF\";\n    const endColor = this.color ? this.color[$toStyle]() : \"#000000\";\n    const width = 5;\n    const cmd = \"repeating-linear-gradient\";\n    const colors = `${startColor},${startColor} ${width}px,${endColor} ${width}px,${endColor} ${2 * width}px`;\n    switch (this.type) {\n      case \"crossHatch\":\n        return `${cmd}(to top,${colors}) ${cmd}(to right,${colors})`;\n      case \"crossDiagonal\":\n        return `${cmd}(45deg,${colors}) ${cmd}(-45deg,${colors})`;\n      case \"diagonalLeft\":\n        return `${cmd}(45deg,${colors})`;\n      case \"diagonalRight\":\n        return `${cmd}(-45deg,${colors})`;\n      case \"horizontal\":\n        return `${cmd}(to top,${colors})`;\n      case \"vertical\":\n        return `${cmd}(to right,${colors})`;\n    }\n    return \"\";\n  }\n}\nclass Picture extends StringObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"picture\");\n    this.id = attributes.id || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass Proto extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"proto\", true);\n    this.appearanceFilter = new XFAObjectArray();\n    this.arc = new XFAObjectArray();\n    this.area = new XFAObjectArray();\n    this.assist = new XFAObjectArray();\n    this.barcode = new XFAObjectArray();\n    this.bindItems = new XFAObjectArray();\n    this.bookend = new XFAObjectArray();\n    this.boolean = new XFAObjectArray();\n    this.border = new XFAObjectArray();\n    this.break = new XFAObjectArray();\n    this.breakAfter = new XFAObjectArray();\n    this.breakBefore = new XFAObjectArray();\n    this.button = new XFAObjectArray();\n    this.calculate = new XFAObjectArray();\n    this.caption = new XFAObjectArray();\n    this.certificate = new XFAObjectArray();\n    this.certificates = new XFAObjectArray();\n    this.checkButton = new XFAObjectArray();\n    this.choiceList = new XFAObjectArray();\n    this.color = new XFAObjectArray();\n    this.comb = new XFAObjectArray();\n    this.connect = new XFAObjectArray();\n    this.contentArea = new XFAObjectArray();\n    this.corner = new XFAObjectArray();\n    this.date = new XFAObjectArray();\n    this.dateTime = new XFAObjectArray();\n    this.dateTimeEdit = new XFAObjectArray();\n    this.decimal = new XFAObjectArray();\n    this.defaultUi = new XFAObjectArray();\n    this.desc = new XFAObjectArray();\n    this.digestMethod = new XFAObjectArray();\n    this.digestMethods = new XFAObjectArray();\n    this.draw = new XFAObjectArray();\n    this.edge = new XFAObjectArray();\n    this.encoding = new XFAObjectArray();\n    this.encodings = new XFAObjectArray();\n    this.encrypt = new XFAObjectArray();\n    this.encryptData = new XFAObjectArray();\n    this.encryption = new XFAObjectArray();\n    this.encryptionMethod = new XFAObjectArray();\n    this.encryptionMethods = new XFAObjectArray();\n    this.event = new XFAObjectArray();\n    this.exData = new XFAObjectArray();\n    this.exObject = new XFAObjectArray();\n    this.exclGroup = new XFAObjectArray();\n    this.execute = new XFAObjectArray();\n    this.extras = new XFAObjectArray();\n    this.field = new XFAObjectArray();\n    this.fill = new XFAObjectArray();\n    this.filter = new XFAObjectArray();\n    this.float = new XFAObjectArray();\n    this.font = new XFAObjectArray();\n    this.format = new XFAObjectArray();\n    this.handler = new XFAObjectArray();\n    this.hyphenation = new XFAObjectArray();\n    this.image = new XFAObjectArray();\n    this.imageEdit = new XFAObjectArray();\n    this.integer = new XFAObjectArray();\n    this.issuers = new XFAObjectArray();\n    this.items = new XFAObjectArray();\n    this.keep = new XFAObjectArray();\n    this.keyUsage = new XFAObjectArray();\n    this.line = new XFAObjectArray();\n    this.linear = new XFAObjectArray();\n    this.lockDocument = new XFAObjectArray();\n    this.manifest = new XFAObjectArray();\n    this.margin = new XFAObjectArray();\n    this.mdp = new XFAObjectArray();\n    this.medium = new XFAObjectArray();\n    this.message = new XFAObjectArray();\n    this.numericEdit = new XFAObjectArray();\n    this.occur = new XFAObjectArray();\n    this.oid = new XFAObjectArray();\n    this.oids = new XFAObjectArray();\n    this.overflow = new XFAObjectArray();\n    this.pageArea = new XFAObjectArray();\n    this.pageSet = new XFAObjectArray();\n    this.para = new XFAObjectArray();\n    this.passwordEdit = new XFAObjectArray();\n    this.pattern = new XFAObjectArray();\n    this.picture = new XFAObjectArray();\n    this.radial = new XFAObjectArray();\n    this.reason = new XFAObjectArray();\n    this.reasons = new XFAObjectArray();\n    this.rectangle = new XFAObjectArray();\n    this.ref = new XFAObjectArray();\n    this.script = new XFAObjectArray();\n    this.setProperty = new XFAObjectArray();\n    this.signData = new XFAObjectArray();\n    this.signature = new XFAObjectArray();\n    this.signing = new XFAObjectArray();\n    this.solid = new XFAObjectArray();\n    this.speak = new XFAObjectArray();\n    this.stipple = new XFAObjectArray();\n    this.subform = new XFAObjectArray();\n    this.subformSet = new XFAObjectArray();\n    this.subjectDN = new XFAObjectArray();\n    this.subjectDNs = new XFAObjectArray();\n    this.submit = new XFAObjectArray();\n    this.text = new XFAObjectArray();\n    this.textEdit = new XFAObjectArray();\n    this.time = new XFAObjectArray();\n    this.timeStamp = new XFAObjectArray();\n    this.toolTip = new XFAObjectArray();\n    this.traversal = new XFAObjectArray();\n    this.traverse = new XFAObjectArray();\n    this.ui = new XFAObjectArray();\n    this.validate = new XFAObjectArray();\n    this.value = new XFAObjectArray();\n    this.variables = new XFAObjectArray();\n  }\n}\nclass Radial extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"radial\", true);\n    this.id = attributes.id || \"\";\n    this.type = getStringOption(attributes.type, [\"toEdge\", \"toCenter\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.color = null;\n    this.extras = null;\n  }\n  [$toStyle](startColor) {\n    startColor = startColor ? startColor[$toStyle]() : \"#FFFFFF\";\n    const endColor = this.color ? this.color[$toStyle]() : \"#000000\";\n    const colors = this.type === \"toEdge\" ? `${startColor},${endColor}` : `${endColor},${startColor}`;\n    return `radial-gradient(circle at center, ${colors})`;\n  }\n}\nclass Reason extends StringObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"reason\");\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass Reasons extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"reasons\", true);\n    this.id = attributes.id || \"\";\n    this.type = getStringOption(attributes.type, [\"optional\", \"required\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.reason = new XFAObjectArray();\n  }\n}\nclass Rectangle extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"rectangle\", true);\n    this.hand = getStringOption(attributes.hand, [\"even\", \"left\", \"right\"]);\n    this.id = attributes.id || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.corner = new XFAObjectArray(4);\n    this.edge = new XFAObjectArray(4);\n    this.fill = null;\n  }\n  [$toHTML]() {\n    const edge = this.edge.children.length ? this.edge.children[0] : new Edge({});\n    const edgeStyle = edge[$toStyle]();\n    const style = Object.create(null);\n    if (this.fill?.presence === \"visible\") {\n      Object.assign(style, this.fill[$toStyle]());\n    } else {\n      style.fill = \"transparent\";\n    }\n    style.strokeWidth = measureToString(edge.presence === \"visible\" ? edge.thickness : 0);\n    style.stroke = edgeStyle.color;\n    const corner = this.corner.children.length ? this.corner.children[0] : new Corner({});\n    const cornerStyle = corner[$toStyle]();\n    const rect = {\n      name: \"rect\",\n      attributes: {\n        xmlns: SVG_NS,\n        width: \"100%\",\n        height: \"100%\",\n        x: 0,\n        y: 0,\n        rx: cornerStyle.radius,\n        ry: cornerStyle.radius,\n        style\n      }\n    };\n    const svg = {\n      name: \"svg\",\n      children: [rect],\n      attributes: {\n        xmlns: SVG_NS,\n        style: {\n          overflow: \"visible\"\n        },\n        width: \"100%\",\n        height: \"100%\"\n      }\n    };\n    const parent = this[$getParent]()[$getParent]();\n    if (hasMargin(parent)) {\n      return HTMLResult.success({\n        name: \"div\",\n        attributes: {\n          style: {\n            display: \"inline\",\n            width: \"100%\",\n            height: \"100%\"\n          }\n        },\n        children: [svg]\n      });\n    }\n    svg.attributes.style.position = \"absolute\";\n    return HTMLResult.success(svg);\n  }\n}\nclass RefElement extends StringObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"ref\");\n    this.id = attributes.id || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass Script extends StringObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"script\");\n    this.binding = attributes.binding || \"\";\n    this.contentType = attributes.contentType || \"\";\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.runAt = getStringOption(attributes.runAt, [\"client\", \"both\", \"server\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass SetProperty extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"setProperty\");\n    this.connection = attributes.connection || \"\";\n    this.ref = attributes.ref || \"\";\n    this.target = attributes.target || \"\";\n  }\n}\nclass SignData extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"signData\", true);\n    this.id = attributes.id || \"\";\n    this.operation = getStringOption(attributes.operation, [\"sign\", \"clear\", \"verify\"]);\n    this.ref = attributes.ref || \"\";\n    this.target = attributes.target || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.filter = null;\n    this.manifest = null;\n  }\n}\nclass Signature extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"signature\", true);\n    this.id = attributes.id || \"\";\n    this.type = getStringOption(attributes.type, [\"PDF1.3\", \"PDF1.6\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.border = null;\n    this.extras = null;\n    this.filter = null;\n    this.manifest = null;\n    this.margin = null;\n  }\n}\nclass Signing extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"signing\", true);\n    this.id = attributes.id || \"\";\n    this.type = getStringOption(attributes.type, [\"optional\", \"required\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.certificate = new XFAObjectArray();\n  }\n}\nclass Solid extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"solid\", true);\n    this.id = attributes.id || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.extras = null;\n  }\n  [$toStyle](startColor) {\n    return startColor ? startColor[$toStyle]() : \"#FFFFFF\";\n  }\n}\nclass Speak extends StringObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"speak\");\n    this.disable = getInteger({\n      data: attributes.disable,\n      defaultValue: 0,\n      validate: x => x === 1\n    });\n    this.id = attributes.id || \"\";\n    this.priority = getStringOption(attributes.priority, [\"custom\", \"caption\", \"name\", \"toolTip\"]);\n    this.rid = attributes.rid || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass Stipple extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"stipple\", true);\n    this.id = attributes.id || \"\";\n    this.rate = getInteger({\n      data: attributes.rate,\n      defaultValue: 50,\n      validate: x => x >= 0 && x <= 100\n    });\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.color = null;\n    this.extras = null;\n  }\n  [$toStyle](bgColor) {\n    const alpha = this.rate / 100;\n    return Util.makeHexColor(Math.round(bgColor.value.r * (1 - alpha) + this.value.r * alpha), Math.round(bgColor.value.g * (1 - alpha) + this.value.g * alpha), Math.round(bgColor.value.b * (1 - alpha) + this.value.b * alpha));\n  }\n}\nclass Subform extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"subform\", true);\n    this.access = getStringOption(attributes.access, [\"open\", \"nonInteractive\", \"protected\", \"readOnly\"]);\n    this.allowMacro = getInteger({\n      data: attributes.allowMacro,\n      defaultValue: 0,\n      validate: x => x === 1\n    });\n    this.anchorType = getStringOption(attributes.anchorType, [\"topLeft\", \"bottomCenter\", \"bottomLeft\", \"bottomRight\", \"middleCenter\", \"middleLeft\", \"middleRight\", \"topCenter\", \"topRight\"]);\n    this.colSpan = getInteger({\n      data: attributes.colSpan,\n      defaultValue: 1,\n      validate: n => n >= 1 || n === -1\n    });\n    this.columnWidths = (attributes.columnWidths || \"\").trim().split(/\\s+/).map(x => x === \"-1\" ? -1 : getMeasurement(x));\n    this.h = attributes.h ? getMeasurement(attributes.h) : \"\";\n    this.hAlign = getStringOption(attributes.hAlign, [\"left\", \"center\", \"justify\", \"justifyAll\", \"radix\", \"right\"]);\n    this.id = attributes.id || \"\";\n    this.layout = getStringOption(attributes.layout, [\"position\", \"lr-tb\", \"rl-row\", \"rl-tb\", \"row\", \"table\", \"tb\"]);\n    this.locale = attributes.locale || \"\";\n    this.maxH = getMeasurement(attributes.maxH, \"0pt\");\n    this.maxW = getMeasurement(attributes.maxW, \"0pt\");\n    this.mergeMode = getStringOption(attributes.mergeMode, [\"consumeData\", \"matchTemplate\"]);\n    this.minH = getMeasurement(attributes.minH, \"0pt\");\n    this.minW = getMeasurement(attributes.minW, \"0pt\");\n    this.name = attributes.name || \"\";\n    this.presence = getStringOption(attributes.presence, [\"visible\", \"hidden\", \"inactive\", \"invisible\"]);\n    this.relevant = getRelevant(attributes.relevant);\n    this.restoreState = getStringOption(attributes.restoreState, [\"manual\", \"auto\"]);\n    this.scope = getStringOption(attributes.scope, [\"name\", \"none\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.w = attributes.w ? getMeasurement(attributes.w) : \"\";\n    this.x = getMeasurement(attributes.x, \"0pt\");\n    this.y = getMeasurement(attributes.y, \"0pt\");\n    this.assist = null;\n    this.bind = null;\n    this.bookend = null;\n    this.border = null;\n    this.break = null;\n    this.calculate = null;\n    this.desc = null;\n    this.extras = null;\n    this.keep = null;\n    this.margin = null;\n    this.occur = null;\n    this.overflow = null;\n    this.pageSet = null;\n    this.para = null;\n    this.traversal = null;\n    this.validate = null;\n    this.variables = null;\n    this.area = new XFAObjectArray();\n    this.breakAfter = new XFAObjectArray();\n    this.breakBefore = new XFAObjectArray();\n    this.connect = new XFAObjectArray();\n    this.draw = new XFAObjectArray();\n    this.event = new XFAObjectArray();\n    this.exObject = new XFAObjectArray();\n    this.exclGroup = new XFAObjectArray();\n    this.field = new XFAObjectArray();\n    this.proto = new XFAObjectArray();\n    this.setProperty = new XFAObjectArray();\n    this.subform = new XFAObjectArray();\n    this.subformSet = new XFAObjectArray();\n  }\n  [$getSubformParent]() {\n    const parent = this[$getParent]();\n    if (parent instanceof SubformSet) {\n      return parent[$getSubformParent]();\n    }\n    return parent;\n  }\n  [$isBindable]() {\n    return true;\n  }\n  [$isThereMoreWidth]() {\n    return this.layout.endsWith(\"-tb\") && this[$extra].attempt === 0 && this[$extra].numberInLine > 0 || this[$getParent]()[$isThereMoreWidth]();\n  }\n  *[$getContainedChildren]() {\n    yield* getContainedChildren(this);\n  }\n  [$flushHTML]() {\n    return flushHTML(this);\n  }\n  [$addHTML](html, bbox) {\n    addHTML(this, html, bbox);\n  }\n  [$getAvailableSpace]() {\n    return getAvailableSpace(this);\n  }\n  [$isSplittable]() {\n    const parent = this[$getSubformParent]();\n    if (!parent[$isSplittable]()) {\n      return false;\n    }\n    if (this[$extra]._isSplittable !== undefined) {\n      return this[$extra]._isSplittable;\n    }\n    if (this.layout === \"position\" || this.layout.includes(\"row\")) {\n      this[$extra]._isSplittable = false;\n      return false;\n    }\n    if (this.keep && this.keep.intact !== \"none\") {\n      this[$extra]._isSplittable = false;\n      return false;\n    }\n    if (parent.layout?.endsWith(\"-tb\") && parent[$extra].numberInLine !== 0) {\n      return false;\n    }\n    this[$extra]._isSplittable = true;\n    return true;\n  }\n  [$toHTML](availableSpace) {\n    setTabIndex(this);\n    if (this.break) {\n      if (this.break.after !== \"auto\" || this.break.afterTarget !== \"\") {\n        const node = new BreakAfter({\n          targetType: this.break.after,\n          target: this.break.afterTarget,\n          startNew: this.break.startNew.toString()\n        });\n        node[$globalData] = this[$globalData];\n        this[$appendChild](node);\n        this.breakAfter.push(node);\n      }\n      if (this.break.before !== \"auto\" || this.break.beforeTarget !== \"\") {\n        const node = new BreakBefore({\n          targetType: this.break.before,\n          target: this.break.beforeTarget,\n          startNew: this.break.startNew.toString()\n        });\n        node[$globalData] = this[$globalData];\n        this[$appendChild](node);\n        this.breakBefore.push(node);\n      }\n      if (this.break.overflowTarget !== \"\") {\n        const node = new Overflow({\n          target: this.break.overflowTarget,\n          leader: this.break.overflowLeader,\n          trailer: this.break.overflowTrailer\n        });\n        node[$globalData] = this[$globalData];\n        this[$appendChild](node);\n        this.overflow.push(node);\n      }\n      this[$removeChild](this.break);\n      this.break = null;\n    }\n    if (this.presence === \"hidden\" || this.presence === \"inactive\") {\n      return HTMLResult.EMPTY;\n    }\n    if (this.breakBefore.children.length > 1 || this.breakAfter.children.length > 1) {\n      warn(\"XFA - Several breakBefore or breakAfter in subforms: please file a bug.\");\n    }\n    if (this.breakBefore.children.length >= 1) {\n      const breakBefore = this.breakBefore.children[0];\n      if (handleBreak(breakBefore)) {\n        return HTMLResult.breakNode(breakBefore);\n      }\n    }\n    if (this[$extra]?.afterBreakAfter) {\n      return HTMLResult.EMPTY;\n    }\n    fixDimensions(this);\n    const children = [];\n    const attributes = {\n      id: this[$uid],\n      class: []\n    };\n    setAccess(this, attributes.class);\n    if (!this[$extra]) {\n      this[$extra] = Object.create(null);\n    }\n    Object.assign(this[$extra], {\n      children,\n      line: null,\n      attributes,\n      attempt: 0,\n      numberInLine: 0,\n      availableSpace: {\n        width: Math.min(this.w || Infinity, availableSpace.width),\n        height: Math.min(this.h || Infinity, availableSpace.height)\n      },\n      width: 0,\n      height: 0,\n      prevHeight: 0,\n      currentWidth: 0\n    });\n    const root = this[$getTemplateRoot]();\n    const savedNoLayoutFailure = root[$extra].noLayoutFailure;\n    const isSplittable = this[$isSplittable]();\n    if (!isSplittable) {\n      setFirstUnsplittable(this);\n    }\n    if (!checkDimensions(this, availableSpace)) {\n      return HTMLResult.FAILURE;\n    }\n    const filter = new Set([\"area\", \"draw\", \"exclGroup\", \"field\", \"subform\", \"subformSet\"]);\n    if (this.layout.includes(\"row\")) {\n      const columnWidths = this[$getSubformParent]().columnWidths;\n      if (Array.isArray(columnWidths) && columnWidths.length > 0) {\n        this[$extra].columnWidths = columnWidths;\n        this[$extra].currentColumn = 0;\n      }\n    }\n    const style = toStyle(this, \"anchorType\", \"dimensions\", \"position\", \"presence\", \"border\", \"margin\", \"hAlign\");\n    const classNames = [\"xfaSubform\"];\n    const cl = layoutClass(this);\n    if (cl) {\n      classNames.push(cl);\n    }\n    attributes.style = style;\n    attributes.class = classNames;\n    if (this.name) {\n      attributes.xfaName = this.name;\n    }\n    if (this.overflow) {\n      const overflowExtra = this.overflow[$getExtra]();\n      if (overflowExtra.addLeader) {\n        overflowExtra.addLeader = false;\n        handleOverflow(this, overflowExtra.leader, availableSpace);\n      }\n    }\n    this[$pushPara]();\n    const isLrTb = this.layout === \"lr-tb\" || this.layout === \"rl-tb\";\n    const maxRun = isLrTb ? MAX_ATTEMPTS_FOR_LRTB_LAYOUT : 1;\n    for (; this[$extra].attempt < maxRun; this[$extra].attempt++) {\n      if (isLrTb && this[$extra].attempt === MAX_ATTEMPTS_FOR_LRTB_LAYOUT - 1) {\n        this[$extra].numberInLine = 0;\n      }\n      const result = this[$childrenToHTML]({\n        filter,\n        include: true\n      });\n      if (result.success) {\n        break;\n      }\n      if (result.isBreak()) {\n        this[$popPara]();\n        return result;\n      }\n      if (isLrTb && this[$extra].attempt === 0 && this[$extra].numberInLine === 0 && !root[$extra].noLayoutFailure) {\n        this[$extra].attempt = maxRun;\n        break;\n      }\n    }\n    this[$popPara]();\n    if (!isSplittable) {\n      unsetFirstUnsplittable(this);\n    }\n    root[$extra].noLayoutFailure = savedNoLayoutFailure;\n    if (this[$extra].attempt === maxRun) {\n      if (this.overflow) {\n        this[$getTemplateRoot]()[$extra].overflowNode = this.overflow;\n      }\n      if (!isSplittable) {\n        delete this[$extra];\n      }\n      return HTMLResult.FAILURE;\n    }\n    if (this.overflow) {\n      const overflowExtra = this.overflow[$getExtra]();\n      if (overflowExtra.addTrailer) {\n        overflowExtra.addTrailer = false;\n        handleOverflow(this, overflowExtra.trailer, availableSpace);\n      }\n    }\n    let marginH = 0;\n    let marginV = 0;\n    if (this.margin) {\n      marginH = this.margin.leftInset + this.margin.rightInset;\n      marginV = this.margin.topInset + this.margin.bottomInset;\n    }\n    const width = Math.max(this[$extra].width + marginH, this.w || 0);\n    const height = Math.max(this[$extra].height + marginV, this.h || 0);\n    const bbox = [this.x, this.y, width, height];\n    if (this.w === \"\") {\n      style.width = measureToString(width);\n    }\n    if (this.h === \"\") {\n      style.height = measureToString(height);\n    }\n    if ((style.width === \"0px\" || style.height === \"0px\") && children.length === 0) {\n      return HTMLResult.EMPTY;\n    }\n    const html = {\n      name: \"div\",\n      attributes,\n      children\n    };\n    applyAssist(this, attributes);\n    const result = HTMLResult.success(createWrapper(this, html), bbox);\n    if (this.breakAfter.children.length >= 1) {\n      const breakAfter = this.breakAfter.children[0];\n      if (handleBreak(breakAfter)) {\n        this[$extra].afterBreakAfter = result;\n        return HTMLResult.breakNode(breakAfter);\n      }\n    }\n    delete this[$extra];\n    return result;\n  }\n}\nclass SubformSet extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"subformSet\", true);\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.relation = getStringOption(attributes.relation, [\"ordered\", \"choice\", \"unordered\"]);\n    this.relevant = getRelevant(attributes.relevant);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.bookend = null;\n    this.break = null;\n    this.desc = null;\n    this.extras = null;\n    this.occur = null;\n    this.overflow = null;\n    this.breakAfter = new XFAObjectArray();\n    this.breakBefore = new XFAObjectArray();\n    this.subform = new XFAObjectArray();\n    this.subformSet = new XFAObjectArray();\n  }\n  *[$getContainedChildren]() {\n    yield* getContainedChildren(this);\n  }\n  [$getSubformParent]() {\n    let parent = this[$getParent]();\n    while (!(parent instanceof Subform)) {\n      parent = parent[$getParent]();\n    }\n    return parent;\n  }\n  [$isBindable]() {\n    return true;\n  }\n}\nclass SubjectDN extends ContentObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"subjectDN\");\n    this.delimiter = attributes.delimiter || \",\";\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n  [$finalize]() {\n    this[$content] = new Map(this[$content].split(this.delimiter).map(kv => {\n      kv = kv.split(\"=\", 2);\n      kv[0] = kv[0].trim();\n      return kv;\n    }));\n  }\n}\nclass SubjectDNs extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"subjectDNs\", true);\n    this.id = attributes.id || \"\";\n    this.type = getStringOption(attributes.type, [\"optional\", \"required\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.subjectDN = new XFAObjectArray();\n  }\n}\nclass Submit extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"submit\", true);\n    this.embedPDF = getInteger({\n      data: attributes.embedPDF,\n      defaultValue: 0,\n      validate: x => x === 1\n    });\n    this.format = getStringOption(attributes.format, [\"xdp\", \"formdata\", \"pdf\", \"urlencoded\", \"xfd\", \"xml\"]);\n    this.id = attributes.id || \"\";\n    this.target = attributes.target || \"\";\n    this.textEncoding = getKeyword({\n      data: attributes.textEncoding ? attributes.textEncoding.toLowerCase() : \"\",\n      defaultValue: \"\",\n      validate: k => [\"utf-8\", \"big-five\", \"fontspecific\", \"gbk\", \"gb-18030\", \"gb-2312\", \"ksc-5601\", \"none\", \"shift-jis\", \"ucs-2\", \"utf-16\"].includes(k) || k.match(/iso-8859-\\d{2}/)\n    });\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.xdpContent = attributes.xdpContent || \"\";\n    this.encrypt = null;\n    this.encryptData = new XFAObjectArray();\n    this.signData = new XFAObjectArray();\n  }\n}\nclass Template extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"template\", true);\n    this.baseProfile = getStringOption(attributes.baseProfile, [\"full\", \"interactiveForms\"]);\n    this.extras = null;\n    this.subform = new XFAObjectArray();\n  }\n  [$finalize]() {\n    if (this.subform.children.length === 0) {\n      warn(\"XFA - No subforms in template node.\");\n    }\n    if (this.subform.children.length >= 2) {\n      warn(\"XFA - Several subforms in template node: please file a bug.\");\n    }\n    this[$tabIndex] = DEFAULT_TAB_INDEX;\n  }\n  [$isSplittable]() {\n    return true;\n  }\n  [$searchNode](expr, container) {\n    if (expr.startsWith(\"#\")) {\n      return [this[$ids].get(expr.slice(1))];\n    }\n    return searchNode(this, container, expr, true, true);\n  }\n  *[$toPages]() {\n    if (!this.subform.children.length) {\n      return HTMLResult.success({\n        name: \"div\",\n        children: []\n      });\n    }\n    this[$extra] = {\n      overflowNode: null,\n      firstUnsplittable: null,\n      currentContentArea: null,\n      currentPageArea: null,\n      noLayoutFailure: false,\n      pageNumber: 1,\n      pagePosition: \"first\",\n      oddOrEven: \"odd\",\n      blankOrNotBlank: \"nonBlank\",\n      paraStack: []\n    };\n    const root = this.subform.children[0];\n    root.pageSet[$cleanPage]();\n    const pageAreas = root.pageSet.pageArea.children;\n    const mainHtml = {\n      name: \"div\",\n      children: []\n    };\n    let pageArea = null;\n    let breakBefore = null;\n    let breakBeforeTarget = null;\n    if (root.breakBefore.children.length >= 1) {\n      breakBefore = root.breakBefore.children[0];\n      breakBeforeTarget = breakBefore.target;\n    } else if (root.subform.children.length >= 1 && root.subform.children[0].breakBefore.children.length >= 1) {\n      breakBefore = root.subform.children[0].breakBefore.children[0];\n      breakBeforeTarget = breakBefore.target;\n    } else if (root.break?.beforeTarget) {\n      breakBefore = root.break;\n      breakBeforeTarget = breakBefore.beforeTarget;\n    } else if (root.subform.children.length >= 1 && root.subform.children[0].break?.beforeTarget) {\n      breakBefore = root.subform.children[0].break;\n      breakBeforeTarget = breakBefore.beforeTarget;\n    }\n    if (breakBefore) {\n      const target = this[$searchNode](breakBeforeTarget, breakBefore[$getParent]());\n      if (target instanceof PageArea) {\n        pageArea = target;\n        breakBefore[$extra] = {};\n      }\n    }\n    if (!pageArea) {\n      pageArea = pageAreas[0];\n    }\n    pageArea[$extra] = {\n      numberOfUse: 1\n    };\n    const pageAreaParent = pageArea[$getParent]();\n    pageAreaParent[$extra] = {\n      numberOfUse: 1,\n      pageIndex: pageAreaParent.pageArea.children.indexOf(pageArea),\n      pageSetIndex: 0\n    };\n    let targetPageArea;\n    let leader = null;\n    let trailer = null;\n    let hasSomething = true;\n    let hasSomethingCounter = 0;\n    let startIndex = 0;\n    while (true) {\n      if (!hasSomething) {\n        mainHtml.children.pop();\n        if (++hasSomethingCounter === MAX_EMPTY_PAGES) {\n          warn(\"XFA - Something goes wrong: please file a bug.\");\n          return mainHtml;\n        }\n      } else {\n        hasSomethingCounter = 0;\n      }\n      targetPageArea = null;\n      this[$extra].currentPageArea = pageArea;\n      const page = pageArea[$toHTML]().html;\n      mainHtml.children.push(page);\n      if (leader) {\n        this[$extra].noLayoutFailure = true;\n        page.children.push(leader[$toHTML](pageArea[$extra].space).html);\n        leader = null;\n      }\n      if (trailer) {\n        this[$extra].noLayoutFailure = true;\n        page.children.push(trailer[$toHTML](pageArea[$extra].space).html);\n        trailer = null;\n      }\n      const contentAreas = pageArea.contentArea.children;\n      const htmlContentAreas = page.children.filter(node => node.attributes.class.includes(\"xfaContentarea\"));\n      hasSomething = false;\n      this[$extra].firstUnsplittable = null;\n      this[$extra].noLayoutFailure = false;\n      const flush = index => {\n        const html = root[$flushHTML]();\n        if (html) {\n          hasSomething ||= html.children?.length > 0;\n          htmlContentAreas[index].children.push(html);\n        }\n      };\n      for (let i = startIndex, ii = contentAreas.length; i < ii; i++) {\n        const contentArea = this[$extra].currentContentArea = contentAreas[i];\n        const space = {\n          width: contentArea.w,\n          height: contentArea.h\n        };\n        startIndex = 0;\n        if (leader) {\n          htmlContentAreas[i].children.push(leader[$toHTML](space).html);\n          leader = null;\n        }\n        if (trailer) {\n          htmlContentAreas[i].children.push(trailer[$toHTML](space).html);\n          trailer = null;\n        }\n        const html = root[$toHTML](space);\n        if (html.success) {\n          if (html.html) {\n            hasSomething ||= html.html.children?.length > 0;\n            htmlContentAreas[i].children.push(html.html);\n          } else if (!hasSomething && mainHtml.children.length > 1) {\n            mainHtml.children.pop();\n          }\n          return mainHtml;\n        }\n        if (html.isBreak()) {\n          const node = html.breakNode;\n          flush(i);\n          if (node.targetType === \"auto\") {\n            continue;\n          }\n          if (node.leader) {\n            leader = this[$searchNode](node.leader, node[$getParent]());\n            leader = leader ? leader[0] : null;\n          }\n          if (node.trailer) {\n            trailer = this[$searchNode](node.trailer, node[$getParent]());\n            trailer = trailer ? trailer[0] : null;\n          }\n          if (node.targetType === \"pageArea\") {\n            targetPageArea = node[$extra].target;\n            i = Infinity;\n          } else if (!node[$extra].target) {\n            i = node[$extra].index;\n          } else {\n            targetPageArea = node[$extra].target;\n            startIndex = node[$extra].index + 1;\n            i = Infinity;\n          }\n          continue;\n        }\n        if (this[$extra].overflowNode) {\n          const node = this[$extra].overflowNode;\n          this[$extra].overflowNode = null;\n          const overflowExtra = node[$getExtra]();\n          const target = overflowExtra.target;\n          overflowExtra.addLeader = overflowExtra.leader !== null;\n          overflowExtra.addTrailer = overflowExtra.trailer !== null;\n          flush(i);\n          const currentIndex = i;\n          i = Infinity;\n          if (target instanceof PageArea) {\n            targetPageArea = target;\n          } else if (target instanceof ContentArea) {\n            const index = contentAreas.indexOf(target);\n            if (index !== -1) {\n              if (index > currentIndex) {\n                i = index - 1;\n              } else {\n                startIndex = index;\n              }\n            } else {\n              targetPageArea = target[$getParent]();\n              startIndex = targetPageArea.contentArea.children.indexOf(target);\n            }\n          }\n          continue;\n        }\n        flush(i);\n      }\n      this[$extra].pageNumber += 1;\n      if (targetPageArea) {\n        if (targetPageArea[$isUsable]()) {\n          targetPageArea[$extra].numberOfUse += 1;\n        } else {\n          targetPageArea = null;\n        }\n      }\n      pageArea = targetPageArea || pageArea[$getNextPage]();\n      yield null;\n    }\n  }\n}\nclass Text extends ContentObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"text\");\n    this.id = attributes.id || \"\";\n    this.maxChars = getInteger({\n      data: attributes.maxChars,\n      defaultValue: 0,\n      validate: x => x >= 0\n    });\n    this.name = attributes.name || \"\";\n    this.rid = attributes.rid || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n  [$acceptWhitespace]() {\n    return true;\n  }\n  [$onChild](child) {\n    if (child[$namespaceId] === NamespaceIds.xhtml.id) {\n      this[$content] = child;\n      return true;\n    }\n    warn(`XFA - Invalid content in Text: ${child[$nodeName]}.`);\n    return false;\n  }\n  [$onText](str) {\n    if (this[$content] instanceof XFAObject) {\n      return;\n    }\n    super[$onText](str);\n  }\n  [$finalize]() {\n    if (typeof this[$content] === \"string\") {\n      this[$content] = this[$content].replaceAll(\"\\r\\n\", \"\\n\");\n    }\n  }\n  [$getExtra]() {\n    if (typeof this[$content] === \"string\") {\n      return this[$content].split(/[\\u2029\\u2028\\n]/).reduce((acc, line) => {\n        if (line) {\n          acc.push(line);\n        }\n        return acc;\n      }, []).join(\"\\n\");\n    }\n    return this[$content][$text]();\n  }\n  [$toHTML](availableSpace) {\n    if (typeof this[$content] === \"string\") {\n      const html = valueToHtml(this[$content]).html;\n      if (this[$content].includes(\"\\u2029\")) {\n        html.name = \"div\";\n        html.children = [];\n        this[$content].split(\"\\u2029\").map(para => para.split(/[\\u2028\\n]/).reduce((acc, line) => {\n          acc.push({\n            name: \"span\",\n            value: line\n          }, {\n            name: \"br\"\n          });\n          return acc;\n        }, [])).forEach(lines => {\n          html.children.push({\n            name: \"p\",\n            children: lines\n          });\n        });\n      } else if (/[\\u2028\\n]/.test(this[$content])) {\n        html.name = \"div\";\n        html.children = [];\n        this[$content].split(/[\\u2028\\n]/).forEach(line => {\n          html.children.push({\n            name: \"span\",\n            value: line\n          }, {\n            name: \"br\"\n          });\n        });\n      }\n      return HTMLResult.success(html);\n    }\n    return this[$content][$toHTML](availableSpace);\n  }\n}\nclass TextEdit extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"textEdit\", true);\n    this.allowRichText = getInteger({\n      data: attributes.allowRichText,\n      defaultValue: 0,\n      validate: x => x === 1\n    });\n    this.hScrollPolicy = getStringOption(attributes.hScrollPolicy, [\"auto\", \"off\", \"on\"]);\n    this.id = attributes.id || \"\";\n    this.multiLine = getInteger({\n      data: attributes.multiLine,\n      defaultValue: \"\",\n      validate: x => x === 0 || x === 1\n    });\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.vScrollPolicy = getStringOption(attributes.vScrollPolicy, [\"auto\", \"off\", \"on\"]);\n    this.border = null;\n    this.comb = null;\n    this.extras = null;\n    this.margin = null;\n  }\n  [$toHTML](availableSpace) {\n    const style = toStyle(this, \"border\", \"font\", \"margin\");\n    let html;\n    const field = this[$getParent]()[$getParent]();\n    if (this.multiLine === \"\") {\n      this.multiLine = field instanceof Draw ? 1 : 0;\n    }\n    if (this.multiLine === 1) {\n      html = {\n        name: \"textarea\",\n        attributes: {\n          dataId: field[$data]?.[$uid] || field[$uid],\n          fieldId: field[$uid],\n          class: [\"xfaTextfield\"],\n          style,\n          \"aria-label\": ariaLabel(field),\n          \"aria-required\": false\n        }\n      };\n    } else {\n      html = {\n        name: \"input\",\n        attributes: {\n          type: \"text\",\n          dataId: field[$data]?.[$uid] || field[$uid],\n          fieldId: field[$uid],\n          class: [\"xfaTextfield\"],\n          style,\n          \"aria-label\": ariaLabel(field),\n          \"aria-required\": false\n        }\n      };\n    }\n    if (isRequired(field)) {\n      html.attributes[\"aria-required\"] = true;\n      html.attributes.required = true;\n    }\n    return HTMLResult.success({\n      name: \"label\",\n      attributes: {\n        class: [\"xfaLabel\"]\n      },\n      children: [html]\n    });\n  }\n}\nclass Time extends StringObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"time\");\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n  [$finalize]() {\n    const date = this[$content].trim();\n    this[$content] = date ? new Date(date) : null;\n  }\n  [$toHTML](availableSpace) {\n    return valueToHtml(this[$content] ? this[$content].toString() : \"\");\n  }\n}\nclass TimeStamp extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"timeStamp\");\n    this.id = attributes.id || \"\";\n    this.server = attributes.server || \"\";\n    this.type = getStringOption(attributes.type, [\"optional\", \"required\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass ToolTip extends StringObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"toolTip\");\n    this.id = attributes.id || \"\";\n    this.rid = attributes.rid || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass Traversal extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"traversal\", true);\n    this.id = attributes.id || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.extras = null;\n    this.traverse = new XFAObjectArray();\n  }\n}\nclass Traverse extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"traverse\", true);\n    this.id = attributes.id || \"\";\n    this.operation = getStringOption(attributes.operation, [\"next\", \"back\", \"down\", \"first\", \"left\", \"right\", \"up\"]);\n    this.ref = attributes.ref || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.extras = null;\n    this.script = null;\n  }\n  get name() {\n    return this.operation;\n  }\n  [$isTransparent]() {\n    return false;\n  }\n}\nclass Ui extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"ui\", true);\n    this.id = attributes.id || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.extras = null;\n    this.picture = null;\n    this.barcode = null;\n    this.button = null;\n    this.checkButton = null;\n    this.choiceList = null;\n    this.dateTimeEdit = null;\n    this.defaultUi = null;\n    this.imageEdit = null;\n    this.numericEdit = null;\n    this.passwordEdit = null;\n    this.signature = null;\n    this.textEdit = null;\n  }\n  [$getExtra]() {\n    if (this[$extra] === undefined) {\n      for (const name of Object.getOwnPropertyNames(this)) {\n        if (name === \"extras\" || name === \"picture\") {\n          continue;\n        }\n        const obj = this[name];\n        if (!(obj instanceof XFAObject)) {\n          continue;\n        }\n        this[$extra] = obj;\n        return obj;\n      }\n      this[$extra] = null;\n    }\n    return this[$extra];\n  }\n  [$toHTML](availableSpace) {\n    const obj = this[$getExtra]();\n    if (obj) {\n      return obj[$toHTML](availableSpace);\n    }\n    return HTMLResult.EMPTY;\n  }\n}\nclass Validate extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"validate\", true);\n    this.formatTest = getStringOption(attributes.formatTest, [\"warning\", \"disabled\", \"error\"]);\n    this.id = attributes.id || \"\";\n    this.nullTest = getStringOption(attributes.nullTest, [\"disabled\", \"error\", \"warning\"]);\n    this.scriptTest = getStringOption(attributes.scriptTest, [\"error\", \"disabled\", \"warning\"]);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.extras = null;\n    this.message = null;\n    this.picture = null;\n    this.script = null;\n  }\n}\nclass Value extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"value\", true);\n    this.id = attributes.id || \"\";\n    this.override = getInteger({\n      data: attributes.override,\n      defaultValue: 0,\n      validate: x => x === 1\n    });\n    this.relevant = getRelevant(attributes.relevant);\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.arc = null;\n    this.boolean = null;\n    this.date = null;\n    this.dateTime = null;\n    this.decimal = null;\n    this.exData = null;\n    this.float = null;\n    this.image = null;\n    this.integer = null;\n    this.line = null;\n    this.rectangle = null;\n    this.text = null;\n    this.time = null;\n  }\n  [$setValue](value) {\n    const parent = this[$getParent]();\n    if (parent instanceof Field) {\n      if (parent.ui?.imageEdit) {\n        if (!this.image) {\n          this.image = new Image({});\n          this[$appendChild](this.image);\n        }\n        this.image[$content] = value[$content];\n        return;\n      }\n    }\n    const valueName = value[$nodeName];\n    if (this[valueName] !== null) {\n      this[valueName][$content] = value[$content];\n      return;\n    }\n    for (const name of Object.getOwnPropertyNames(this)) {\n      const obj = this[name];\n      if (obj instanceof XFAObject) {\n        this[name] = null;\n        this[$removeChild](obj);\n      }\n    }\n    this[value[$nodeName]] = value;\n    this[$appendChild](value);\n  }\n  [$text]() {\n    if (this.exData) {\n      if (typeof this.exData[$content] === \"string\") {\n        return this.exData[$content].trim();\n      }\n      return this.exData[$content][$text]().trim();\n    }\n    for (const name of Object.getOwnPropertyNames(this)) {\n      if (name === \"image\") {\n        continue;\n      }\n      const obj = this[name];\n      if (obj instanceof XFAObject) {\n        return (obj[$content] || \"\").toString().trim();\n      }\n    }\n    return null;\n  }\n  [$toHTML](availableSpace) {\n    for (const name of Object.getOwnPropertyNames(this)) {\n      const obj = this[name];\n      if (!(obj instanceof XFAObject)) {\n        continue;\n      }\n      return obj[$toHTML](availableSpace);\n    }\n    return HTMLResult.EMPTY;\n  }\n}\nclass Variables extends XFAObject {\n  constructor(attributes) {\n    super(TEMPLATE_NS_ID, \"variables\", true);\n    this.id = attributes.id || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n    this.boolean = new XFAObjectArray();\n    this.date = new XFAObjectArray();\n    this.dateTime = new XFAObjectArray();\n    this.decimal = new XFAObjectArray();\n    this.exData = new XFAObjectArray();\n    this.float = new XFAObjectArray();\n    this.image = new XFAObjectArray();\n    this.integer = new XFAObjectArray();\n    this.manifest = new XFAObjectArray();\n    this.script = new XFAObjectArray();\n    this.text = new XFAObjectArray();\n    this.time = new XFAObjectArray();\n  }\n  [$isTransparent]() {\n    return true;\n  }\n}\nclass TemplateNamespace {\n  static [$buildXFAObject](name, attributes) {\n    if (TemplateNamespace.hasOwnProperty(name)) {\n      const node = TemplateNamespace[name](attributes);\n      node[$setSetAttributes](attributes);\n      return node;\n    }\n    return undefined;\n  }\n  static appearanceFilter(attrs) {\n    return new AppearanceFilter(attrs);\n  }\n  static arc(attrs) {\n    return new Arc(attrs);\n  }\n  static area(attrs) {\n    return new Area(attrs);\n  }\n  static assist(attrs) {\n    return new Assist(attrs);\n  }\n  static barcode(attrs) {\n    return new Barcode(attrs);\n  }\n  static bind(attrs) {\n    return new Bind(attrs);\n  }\n  static bindItems(attrs) {\n    return new BindItems(attrs);\n  }\n  static bookend(attrs) {\n    return new Bookend(attrs);\n  }\n  static boolean(attrs) {\n    return new BooleanElement(attrs);\n  }\n  static border(attrs) {\n    return new Border(attrs);\n  }\n  static break(attrs) {\n    return new Break(attrs);\n  }\n  static breakAfter(attrs) {\n    return new BreakAfter(attrs);\n  }\n  static breakBefore(attrs) {\n    return new BreakBefore(attrs);\n  }\n  static button(attrs) {\n    return new Button(attrs);\n  }\n  static calculate(attrs) {\n    return new Calculate(attrs);\n  }\n  static caption(attrs) {\n    return new Caption(attrs);\n  }\n  static certificate(attrs) {\n    return new Certificate(attrs);\n  }\n  static certificates(attrs) {\n    return new Certificates(attrs);\n  }\n  static checkButton(attrs) {\n    return new CheckButton(attrs);\n  }\n  static choiceList(attrs) {\n    return new ChoiceList(attrs);\n  }\n  static color(attrs) {\n    return new Color(attrs);\n  }\n  static comb(attrs) {\n    return new Comb(attrs);\n  }\n  static connect(attrs) {\n    return new Connect(attrs);\n  }\n  static contentArea(attrs) {\n    return new ContentArea(attrs);\n  }\n  static corner(attrs) {\n    return new Corner(attrs);\n  }\n  static date(attrs) {\n    return new DateElement(attrs);\n  }\n  static dateTime(attrs) {\n    return new DateTime(attrs);\n  }\n  static dateTimeEdit(attrs) {\n    return new DateTimeEdit(attrs);\n  }\n  static decimal(attrs) {\n    return new Decimal(attrs);\n  }\n  static defaultUi(attrs) {\n    return new DefaultUi(attrs);\n  }\n  static desc(attrs) {\n    return new Desc(attrs);\n  }\n  static digestMethod(attrs) {\n    return new DigestMethod(attrs);\n  }\n  static digestMethods(attrs) {\n    return new DigestMethods(attrs);\n  }\n  static draw(attrs) {\n    return new Draw(attrs);\n  }\n  static edge(attrs) {\n    return new Edge(attrs);\n  }\n  static encoding(attrs) {\n    return new Encoding(attrs);\n  }\n  static encodings(attrs) {\n    return new Encodings(attrs);\n  }\n  static encrypt(attrs) {\n    return new Encrypt(attrs);\n  }\n  static encryptData(attrs) {\n    return new EncryptData(attrs);\n  }\n  static encryption(attrs) {\n    return new Encryption(attrs);\n  }\n  static encryptionMethod(attrs) {\n    return new EncryptionMethod(attrs);\n  }\n  static encryptionMethods(attrs) {\n    return new EncryptionMethods(attrs);\n  }\n  static event(attrs) {\n    return new Event(attrs);\n  }\n  static exData(attrs) {\n    return new ExData(attrs);\n  }\n  static exObject(attrs) {\n    return new ExObject(attrs);\n  }\n  static exclGroup(attrs) {\n    return new ExclGroup(attrs);\n  }\n  static execute(attrs) {\n    return new Execute(attrs);\n  }\n  static extras(attrs) {\n    return new Extras(attrs);\n  }\n  static field(attrs) {\n    return new Field(attrs);\n  }\n  static fill(attrs) {\n    return new Fill(attrs);\n  }\n  static filter(attrs) {\n    return new Filter(attrs);\n  }\n  static float(attrs) {\n    return new Float(attrs);\n  }\n  static font(attrs) {\n    return new template_Font(attrs);\n  }\n  static format(attrs) {\n    return new Format(attrs);\n  }\n  static handler(attrs) {\n    return new Handler(attrs);\n  }\n  static hyphenation(attrs) {\n    return new Hyphenation(attrs);\n  }\n  static image(attrs) {\n    return new Image(attrs);\n  }\n  static imageEdit(attrs) {\n    return new ImageEdit(attrs);\n  }\n  static integer(attrs) {\n    return new Integer(attrs);\n  }\n  static issuers(attrs) {\n    return new Issuers(attrs);\n  }\n  static items(attrs) {\n    return new Items(attrs);\n  }\n  static keep(attrs) {\n    return new Keep(attrs);\n  }\n  static keyUsage(attrs) {\n    return new KeyUsage(attrs);\n  }\n  static line(attrs) {\n    return new Line(attrs);\n  }\n  static linear(attrs) {\n    return new Linear(attrs);\n  }\n  static lockDocument(attrs) {\n    return new LockDocument(attrs);\n  }\n  static manifest(attrs) {\n    return new Manifest(attrs);\n  }\n  static margin(attrs) {\n    return new Margin(attrs);\n  }\n  static mdp(attrs) {\n    return new Mdp(attrs);\n  }\n  static medium(attrs) {\n    return new Medium(attrs);\n  }\n  static message(attrs) {\n    return new Message(attrs);\n  }\n  static numericEdit(attrs) {\n    return new NumericEdit(attrs);\n  }\n  static occur(attrs) {\n    return new Occur(attrs);\n  }\n  static oid(attrs) {\n    return new Oid(attrs);\n  }\n  static oids(attrs) {\n    return new Oids(attrs);\n  }\n  static overflow(attrs) {\n    return new Overflow(attrs);\n  }\n  static pageArea(attrs) {\n    return new PageArea(attrs);\n  }\n  static pageSet(attrs) {\n    return new PageSet(attrs);\n  }\n  static para(attrs) {\n    return new Para(attrs);\n  }\n  static passwordEdit(attrs) {\n    return new PasswordEdit(attrs);\n  }\n  static pattern(attrs) {\n    return new template_Pattern(attrs);\n  }\n  static picture(attrs) {\n    return new Picture(attrs);\n  }\n  static proto(attrs) {\n    return new Proto(attrs);\n  }\n  static radial(attrs) {\n    return new Radial(attrs);\n  }\n  static reason(attrs) {\n    return new Reason(attrs);\n  }\n  static reasons(attrs) {\n    return new Reasons(attrs);\n  }\n  static rectangle(attrs) {\n    return new Rectangle(attrs);\n  }\n  static ref(attrs) {\n    return new RefElement(attrs);\n  }\n  static script(attrs) {\n    return new Script(attrs);\n  }\n  static setProperty(attrs) {\n    return new SetProperty(attrs);\n  }\n  static signData(attrs) {\n    return new SignData(attrs);\n  }\n  static signature(attrs) {\n    return new Signature(attrs);\n  }\n  static signing(attrs) {\n    return new Signing(attrs);\n  }\n  static solid(attrs) {\n    return new Solid(attrs);\n  }\n  static speak(attrs) {\n    return new Speak(attrs);\n  }\n  static stipple(attrs) {\n    return new Stipple(attrs);\n  }\n  static subform(attrs) {\n    return new Subform(attrs);\n  }\n  static subformSet(attrs) {\n    return new SubformSet(attrs);\n  }\n  static subjectDN(attrs) {\n    return new SubjectDN(attrs);\n  }\n  static subjectDNs(attrs) {\n    return new SubjectDNs(attrs);\n  }\n  static submit(attrs) {\n    return new Submit(attrs);\n  }\n  static template(attrs) {\n    return new Template(attrs);\n  }\n  static text(attrs) {\n    return new Text(attrs);\n  }\n  static textEdit(attrs) {\n    return new TextEdit(attrs);\n  }\n  static time(attrs) {\n    return new Time(attrs);\n  }\n  static timeStamp(attrs) {\n    return new TimeStamp(attrs);\n  }\n  static toolTip(attrs) {\n    return new ToolTip(attrs);\n  }\n  static traversal(attrs) {\n    return new Traversal(attrs);\n  }\n  static traverse(attrs) {\n    return new Traverse(attrs);\n  }\n  static ui(attrs) {\n    return new Ui(attrs);\n  }\n  static validate(attrs) {\n    return new Validate(attrs);\n  }\n  static value(attrs) {\n    return new Value(attrs);\n  }\n  static variables(attrs) {\n    return new Variables(attrs);\n  }\n}\n\n;// ./src/core/xfa/bind.js\n\n\n\n\n\n\nconst bind_NS_DATASETS = NamespaceIds.datasets.id;\nfunction createText(content) {\n  const node = new Text({});\n  node[$content] = content;\n  return node;\n}\nclass Binder {\n  constructor(root) {\n    this.root = root;\n    this.datasets = root.datasets;\n    this.data = root.datasets?.data || new XmlObject(NamespaceIds.datasets.id, \"data\");\n    this.emptyMerge = this.data[$getChildren]().length === 0;\n    this.root.form = this.form = root.template[$clone]();\n  }\n  _isConsumeData() {\n    return !this.emptyMerge && this._mergeMode;\n  }\n  _isMatchTemplate() {\n    return !this._isConsumeData();\n  }\n  bind() {\n    this._bindElement(this.form, this.data);\n    return this.form;\n  }\n  getData() {\n    return this.data;\n  }\n  _bindValue(formNode, data, picture) {\n    formNode[$data] = data;\n    if (formNode[$hasSettableValue]()) {\n      if (data[$isDataValue]()) {\n        const value = data[$getDataValue]();\n        formNode[$setValue](createText(value));\n      } else if (formNode instanceof Field && formNode.ui?.choiceList?.open === \"multiSelect\") {\n        const value = data[$getChildren]().map(child => child[$content].trim()).join(\"\\n\");\n        formNode[$setValue](createText(value));\n      } else if (this._isConsumeData()) {\n        warn(`XFA - Nodes haven't the same type.`);\n      }\n    } else if (!data[$isDataValue]() || this._isMatchTemplate()) {\n      this._bindElement(formNode, data);\n    } else {\n      warn(`XFA - Nodes haven't the same type.`);\n    }\n  }\n  _findDataByNameToConsume(name, isValue, dataNode, global) {\n    if (!name) {\n      return null;\n    }\n    let generator, match;\n    for (let i = 0; i < 3; i++) {\n      generator = dataNode[$getRealChildrenByNameIt](name, false, true);\n      while (true) {\n        match = generator.next().value;\n        if (!match) {\n          break;\n        }\n        if (isValue === match[$isDataValue]()) {\n          return match;\n        }\n      }\n      if (dataNode[$namespaceId] === NamespaceIds.datasets.id && dataNode[$nodeName] === \"data\") {\n        break;\n      }\n      dataNode = dataNode[$getParent]();\n    }\n    if (!global) {\n      return null;\n    }\n    generator = this.data[$getRealChildrenByNameIt](name, true, false);\n    match = generator.next().value;\n    if (match) {\n      return match;\n    }\n    generator = this.data[$getAttributeIt](name, true);\n    match = generator.next().value;\n    if (match?.[$isDataValue]()) {\n      return match;\n    }\n    return null;\n  }\n  _setProperties(formNode, dataNode) {\n    if (!formNode.hasOwnProperty(\"setProperty\")) {\n      return;\n    }\n    for (const {\n      ref,\n      target,\n      connection\n    } of formNode.setProperty.children) {\n      if (connection) {\n        continue;\n      }\n      if (!ref) {\n        continue;\n      }\n      const nodes = searchNode(this.root, dataNode, ref, false, false);\n      if (!nodes) {\n        warn(`XFA - Invalid reference: ${ref}.`);\n        continue;\n      }\n      const [node] = nodes;\n      if (!node[$isDescendent](this.data)) {\n        warn(`XFA - Invalid node: must be a data node.`);\n        continue;\n      }\n      const targetNodes = searchNode(this.root, formNode, target, false, false);\n      if (!targetNodes) {\n        warn(`XFA - Invalid target: ${target}.`);\n        continue;\n      }\n      const [targetNode] = targetNodes;\n      if (!targetNode[$isDescendent](formNode)) {\n        warn(`XFA - Invalid target: must be a property or subproperty.`);\n        continue;\n      }\n      const targetParent = targetNode[$getParent]();\n      if (targetNode instanceof SetProperty || targetParent instanceof SetProperty) {\n        warn(`XFA - Invalid target: cannot be a setProperty or one of its properties.`);\n        continue;\n      }\n      if (targetNode instanceof BindItems || targetParent instanceof BindItems) {\n        warn(`XFA - Invalid target: cannot be a bindItems or one of its properties.`);\n        continue;\n      }\n      const content = node[$text]();\n      const name = targetNode[$nodeName];\n      if (targetNode instanceof XFAAttribute) {\n        const attrs = Object.create(null);\n        attrs[name] = content;\n        const obj = Reflect.construct(Object.getPrototypeOf(targetParent).constructor, [attrs]);\n        targetParent[name] = obj[name];\n        continue;\n      }\n      if (!targetNode.hasOwnProperty($content)) {\n        warn(`XFA - Invalid node to use in setProperty`);\n        continue;\n      }\n      targetNode[$data] = node;\n      targetNode[$content] = content;\n      targetNode[$finalize]();\n    }\n  }\n  _bindItems(formNode, dataNode) {\n    if (!formNode.hasOwnProperty(\"items\") || !formNode.hasOwnProperty(\"bindItems\") || formNode.bindItems.isEmpty()) {\n      return;\n    }\n    for (const item of formNode.items.children) {\n      formNode[$removeChild](item);\n    }\n    formNode.items.clear();\n    const labels = new Items({});\n    const values = new Items({});\n    formNode[$appendChild](labels);\n    formNode.items.push(labels);\n    formNode[$appendChild](values);\n    formNode.items.push(values);\n    for (const {\n      ref,\n      labelRef,\n      valueRef,\n      connection\n    } of formNode.bindItems.children) {\n      if (connection) {\n        continue;\n      }\n      if (!ref) {\n        continue;\n      }\n      const nodes = searchNode(this.root, dataNode, ref, false, false);\n      if (!nodes) {\n        warn(`XFA - Invalid reference: ${ref}.`);\n        continue;\n      }\n      for (const node of nodes) {\n        if (!node[$isDescendent](this.datasets)) {\n          warn(`XFA - Invalid ref (${ref}): must be a datasets child.`);\n          continue;\n        }\n        const labelNodes = searchNode(this.root, node, labelRef, true, false);\n        if (!labelNodes) {\n          warn(`XFA - Invalid label: ${labelRef}.`);\n          continue;\n        }\n        const [labelNode] = labelNodes;\n        if (!labelNode[$isDescendent](this.datasets)) {\n          warn(`XFA - Invalid label: must be a datasets child.`);\n          continue;\n        }\n        const valueNodes = searchNode(this.root, node, valueRef, true, false);\n        if (!valueNodes) {\n          warn(`XFA - Invalid value: ${valueRef}.`);\n          continue;\n        }\n        const [valueNode] = valueNodes;\n        if (!valueNode[$isDescendent](this.datasets)) {\n          warn(`XFA - Invalid value: must be a datasets child.`);\n          continue;\n        }\n        const label = createText(labelNode[$text]());\n        const value = createText(valueNode[$text]());\n        labels[$appendChild](label);\n        labels.text.push(label);\n        values[$appendChild](value);\n        values.text.push(value);\n      }\n    }\n  }\n  _bindOccurrences(formNode, matches, picture) {\n    let baseClone;\n    if (matches.length > 1) {\n      baseClone = formNode[$clone]();\n      baseClone[$removeChild](baseClone.occur);\n      baseClone.occur = null;\n    }\n    this._bindValue(formNode, matches[0], picture);\n    this._setProperties(formNode, matches[0]);\n    this._bindItems(formNode, matches[0]);\n    if (matches.length === 1) {\n      return;\n    }\n    const parent = formNode[$getParent]();\n    const name = formNode[$nodeName];\n    const pos = parent[$indexOf](formNode);\n    for (let i = 1, ii = matches.length; i < ii; i++) {\n      const match = matches[i];\n      const clone = baseClone[$clone]();\n      parent[name].push(clone);\n      parent[$insertAt](pos + i, clone);\n      this._bindValue(clone, match, picture);\n      this._setProperties(clone, match);\n      this._bindItems(clone, match);\n    }\n  }\n  _createOccurrences(formNode) {\n    if (!this.emptyMerge) {\n      return;\n    }\n    const {\n      occur\n    } = formNode;\n    if (!occur || occur.initial <= 1) {\n      return;\n    }\n    const parent = formNode[$getParent]();\n    const name = formNode[$nodeName];\n    if (!(parent[name] instanceof XFAObjectArray)) {\n      return;\n    }\n    let currentNumber;\n    if (formNode.name) {\n      currentNumber = parent[name].children.filter(e => e.name === formNode.name).length;\n    } else {\n      currentNumber = parent[name].children.length;\n    }\n    const pos = parent[$indexOf](formNode) + 1;\n    const ii = occur.initial - currentNumber;\n    if (ii) {\n      const nodeClone = formNode[$clone]();\n      nodeClone[$removeChild](nodeClone.occur);\n      nodeClone.occur = null;\n      parent[name].push(nodeClone);\n      parent[$insertAt](pos, nodeClone);\n      for (let i = 1; i < ii; i++) {\n        const clone = nodeClone[$clone]();\n        parent[name].push(clone);\n        parent[$insertAt](pos + i, clone);\n      }\n    }\n  }\n  _getOccurInfo(formNode) {\n    const {\n      name,\n      occur\n    } = formNode;\n    if (!occur || !name) {\n      return [1, 1];\n    }\n    const max = occur.max === -1 ? Infinity : occur.max;\n    return [occur.min, max];\n  }\n  _setAndBind(formNode, dataNode) {\n    this._setProperties(formNode, dataNode);\n    this._bindItems(formNode, dataNode);\n    this._bindElement(formNode, dataNode);\n  }\n  _bindElement(formNode, dataNode) {\n    const uselessNodes = [];\n    this._createOccurrences(formNode);\n    for (const child of formNode[$getChildren]()) {\n      if (child[$data]) {\n        continue;\n      }\n      if (this._mergeMode === undefined && child[$nodeName] === \"subform\") {\n        this._mergeMode = child.mergeMode === \"consumeData\";\n        const dataChildren = dataNode[$getChildren]();\n        if (dataChildren.length > 0) {\n          this._bindOccurrences(child, [dataChildren[0]], null);\n        } else if (this.emptyMerge) {\n          const nsId = dataNode[$namespaceId] === bind_NS_DATASETS ? -1 : dataNode[$namespaceId];\n          const dataChild = child[$data] = new XmlObject(nsId, child.name || \"root\");\n          dataNode[$appendChild](dataChild);\n          this._bindElement(child, dataChild);\n        }\n        continue;\n      }\n      if (!child[$isBindable]()) {\n        continue;\n      }\n      let global = false;\n      let picture = null;\n      let ref = null;\n      let match = null;\n      if (child.bind) {\n        switch (child.bind.match) {\n          case \"none\":\n            this._setAndBind(child, dataNode);\n            continue;\n          case \"global\":\n            global = true;\n            break;\n          case \"dataRef\":\n            if (!child.bind.ref) {\n              warn(`XFA - ref is empty in node ${child[$nodeName]}.`);\n              this._setAndBind(child, dataNode);\n              continue;\n            }\n            ref = child.bind.ref;\n            break;\n          default:\n            break;\n        }\n        if (child.bind.picture) {\n          picture = child.bind.picture[$content];\n        }\n      }\n      const [min, max] = this._getOccurInfo(child);\n      if (ref) {\n        match = searchNode(this.root, dataNode, ref, true, false);\n        if (match === null) {\n          match = createDataNode(this.data, dataNode, ref);\n          if (!match) {\n            continue;\n          }\n          if (this._isConsumeData()) {\n            match[$consumed] = true;\n          }\n          this._setAndBind(child, match);\n          continue;\n        } else {\n          if (this._isConsumeData()) {\n            match = match.filter(node => !node[$consumed]);\n          }\n          if (match.length > max) {\n            match = match.slice(0, max);\n          } else if (match.length === 0) {\n            match = null;\n          }\n          if (match && this._isConsumeData()) {\n            match.forEach(node => {\n              node[$consumed] = true;\n            });\n          }\n        }\n      } else {\n        if (!child.name) {\n          this._setAndBind(child, dataNode);\n          continue;\n        }\n        if (this._isConsumeData()) {\n          const matches = [];\n          while (matches.length < max) {\n            const found = this._findDataByNameToConsume(child.name, child[$hasSettableValue](), dataNode, global);\n            if (!found) {\n              break;\n            }\n            found[$consumed] = true;\n            matches.push(found);\n          }\n          match = matches.length > 0 ? matches : null;\n        } else {\n          match = dataNode[$getRealChildrenByNameIt](child.name, false, this.emptyMerge).next().value;\n          if (!match) {\n            if (min === 0) {\n              uselessNodes.push(child);\n              continue;\n            }\n            const nsId = dataNode[$namespaceId] === bind_NS_DATASETS ? -1 : dataNode[$namespaceId];\n            match = child[$data] = new XmlObject(nsId, child.name);\n            if (this.emptyMerge) {\n              match[$consumed] = true;\n            }\n            dataNode[$appendChild](match);\n            this._setAndBind(child, match);\n            continue;\n          }\n          if (this.emptyMerge) {\n            match[$consumed] = true;\n          }\n          match = [match];\n        }\n      }\n      if (match) {\n        this._bindOccurrences(child, match, picture);\n      } else if (min > 0) {\n        this._setAndBind(child, dataNode);\n      } else {\n        uselessNodes.push(child);\n      }\n    }\n    uselessNodes.forEach(node => node[$getParent]()[$removeChild](node));\n  }\n}\n\n;// ./src/core/xfa/data.js\n\nclass DataHandler {\n  constructor(root, data) {\n    this.data = data;\n    this.dataset = root.datasets || null;\n  }\n  serialize(storage) {\n    const stack = [[-1, this.data[$getChildren]()]];\n    while (stack.length > 0) {\n      const last = stack.at(-1);\n      const [i, children] = last;\n      if (i + 1 === children.length) {\n        stack.pop();\n        continue;\n      }\n      const child = children[++last[0]];\n      const storageEntry = storage.get(child[$uid]);\n      if (storageEntry) {\n        child[$setValue](storageEntry);\n      } else {\n        const attributes = child[$getAttributes]();\n        for (const value of attributes.values()) {\n          const entry = storage.get(value[$uid]);\n          if (entry) {\n            value[$setValue](entry);\n            break;\n          }\n        }\n      }\n      const nodes = child[$getChildren]();\n      if (nodes.length > 0) {\n        stack.push([-1, nodes]);\n      }\n    }\n    const buf = [`<xfa:datasets xmlns:xfa=\"http://www.xfa.org/schema/xfa-data/1.0/\">`];\n    if (this.dataset) {\n      for (const child of this.dataset[$getChildren]()) {\n        if (child[$nodeName] !== \"data\") {\n          child[$toString](buf);\n        }\n      }\n    }\n    this.data[$toString](buf);\n    buf.push(\"</xfa:datasets>\");\n    return buf.join(\"\");\n  }\n}\n\n;// ./src/core/xfa/config.js\n\n\n\n\n\nconst CONFIG_NS_ID = NamespaceIds.config.id;\nclass Acrobat extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"acrobat\", true);\n    this.acrobat7 = null;\n    this.autoSave = null;\n    this.common = null;\n    this.validate = null;\n    this.validateApprovalSignatures = null;\n    this.submitUrl = new XFAObjectArray();\n  }\n}\nclass Acrobat7 extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"acrobat7\", true);\n    this.dynamicRender = null;\n  }\n}\nclass ADBE_JSConsole extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"ADBE_JSConsole\", [\"delegate\", \"Enable\", \"Disable\"]);\n  }\n}\nclass ADBE_JSDebugger extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"ADBE_JSDebugger\", [\"delegate\", \"Enable\", \"Disable\"]);\n  }\n}\nclass AddSilentPrint extends Option01 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"addSilentPrint\");\n  }\n}\nclass AddViewerPreferences extends Option01 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"addViewerPreferences\");\n  }\n}\nclass AdjustData extends Option10 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"adjustData\");\n  }\n}\nclass AdobeExtensionLevel extends IntegerObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"adobeExtensionLevel\", 0, n => n >= 1 && n <= 8);\n  }\n}\nclass Agent extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"agent\", true);\n    this.name = attributes.name ? attributes.name.trim() : \"\";\n    this.common = new XFAObjectArray();\n  }\n}\nclass AlwaysEmbed extends ContentObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"alwaysEmbed\");\n  }\n}\nclass Amd extends StringObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"amd\");\n  }\n}\nclass config_Area extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"area\");\n    this.level = getInteger({\n      data: attributes.level,\n      defaultValue: 0,\n      validate: n => n >= 1 && n <= 3\n    });\n    this.name = getStringOption(attributes.name, [\"\", \"barcode\", \"coreinit\", \"deviceDriver\", \"font\", \"general\", \"layout\", \"merge\", \"script\", \"signature\", \"sourceSet\", \"templateCache\"]);\n  }\n}\nclass Attributes extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"attributes\", [\"preserve\", \"delegate\", \"ignore\"]);\n  }\n}\nclass AutoSave extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"autoSave\", [\"disabled\", \"enabled\"]);\n  }\n}\nclass Base extends StringObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"base\");\n  }\n}\nclass BatchOutput extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"batchOutput\");\n    this.format = getStringOption(attributes.format, [\"none\", \"concat\", \"zip\", \"zipCompress\"]);\n  }\n}\nclass BehaviorOverride extends ContentObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"behaviorOverride\");\n  }\n  [$finalize]() {\n    this[$content] = new Map(this[$content].trim().split(/\\s+/).filter(x => x.includes(\":\")).map(x => x.split(\":\", 2)));\n  }\n}\nclass Cache extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"cache\", true);\n    this.templateCache = null;\n  }\n}\nclass Change extends Option01 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"change\");\n  }\n}\nclass Common extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"common\", true);\n    this.data = null;\n    this.locale = null;\n    this.localeSet = null;\n    this.messaging = null;\n    this.suppressBanner = null;\n    this.template = null;\n    this.validationMessaging = null;\n    this.versionControl = null;\n    this.log = new XFAObjectArray();\n  }\n}\nclass Compress extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"compress\");\n    this.scope = getStringOption(attributes.scope, [\"imageOnly\", \"document\"]);\n  }\n}\nclass CompressLogicalStructure extends Option01 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"compressLogicalStructure\");\n  }\n}\nclass CompressObjectStream extends Option10 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"compressObjectStream\");\n  }\n}\nclass Compression extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"compression\", true);\n    this.compressLogicalStructure = null;\n    this.compressObjectStream = null;\n    this.level = null;\n    this.type = null;\n  }\n}\nclass Config extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"config\", true);\n    this.acrobat = null;\n    this.present = null;\n    this.trace = null;\n    this.agent = new XFAObjectArray();\n  }\n}\nclass Conformance extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"conformance\", [\"A\", \"B\"]);\n  }\n}\nclass ContentCopy extends Option01 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"contentCopy\");\n  }\n}\nclass Copies extends IntegerObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"copies\", 1, n => n >= 1);\n  }\n}\nclass Creator extends StringObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"creator\");\n  }\n}\nclass CurrentPage extends IntegerObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"currentPage\", 0, n => n >= 0);\n  }\n}\nclass Data extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"data\", true);\n    this.adjustData = null;\n    this.attributes = null;\n    this.incrementalLoad = null;\n    this.outputXSL = null;\n    this.range = null;\n    this.record = null;\n    this.startNode = null;\n    this.uri = null;\n    this.window = null;\n    this.xsl = null;\n    this.excludeNS = new XFAObjectArray();\n    this.transform = new XFAObjectArray();\n  }\n}\nclass Debug extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"debug\", true);\n    this.uri = null;\n  }\n}\nclass DefaultTypeface extends ContentObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"defaultTypeface\");\n    this.writingScript = getStringOption(attributes.writingScript, [\"*\", \"Arabic\", \"Cyrillic\", \"EastEuropeanRoman\", \"Greek\", \"Hebrew\", \"Japanese\", \"Korean\", \"Roman\", \"SimplifiedChinese\", \"Thai\", \"TraditionalChinese\", \"Vietnamese\"]);\n  }\n}\nclass Destination extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"destination\", [\"pdf\", \"pcl\", \"ps\", \"webClient\", \"zpl\"]);\n  }\n}\nclass DocumentAssembly extends Option01 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"documentAssembly\");\n  }\n}\nclass Driver extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"driver\", true);\n    this.name = attributes.name ? attributes.name.trim() : \"\";\n    this.fontInfo = null;\n    this.xdc = null;\n  }\n}\nclass DuplexOption extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"duplexOption\", [\"simplex\", \"duplexFlipLongEdge\", \"duplexFlipShortEdge\"]);\n  }\n}\nclass DynamicRender extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"dynamicRender\", [\"forbidden\", \"required\"]);\n  }\n}\nclass Embed extends Option01 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"embed\");\n  }\n}\nclass config_Encrypt extends Option01 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"encrypt\");\n  }\n}\nclass config_Encryption extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"encryption\", true);\n    this.encrypt = null;\n    this.encryptionLevel = null;\n    this.permissions = null;\n  }\n}\nclass EncryptionLevel extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"encryptionLevel\", [\"40bit\", \"128bit\"]);\n  }\n}\nclass Enforce extends StringObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"enforce\");\n  }\n}\nclass Equate extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"equate\");\n    this.force = getInteger({\n      data: attributes.force,\n      defaultValue: 1,\n      validate: n => n === 0\n    });\n    this.from = attributes.from || \"\";\n    this.to = attributes.to || \"\";\n  }\n}\nclass EquateRange extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"equateRange\");\n    this.from = attributes.from || \"\";\n    this.to = attributes.to || \"\";\n    this._unicodeRange = attributes.unicodeRange || \"\";\n  }\n  get unicodeRange() {\n    const ranges = [];\n    const unicodeRegex = /U\\+([0-9a-fA-F]+)/;\n    const unicodeRange = this._unicodeRange;\n    for (let range of unicodeRange.split(\",\").map(x => x.trim()).filter(x => !!x)) {\n      range = range.split(\"-\", 2).map(x => {\n        const found = x.match(unicodeRegex);\n        if (!found) {\n          return 0;\n        }\n        return parseInt(found[1], 16);\n      });\n      if (range.length === 1) {\n        range.push(range[0]);\n      }\n      ranges.push(range);\n    }\n    return shadow(this, \"unicodeRange\", ranges);\n  }\n}\nclass Exclude extends ContentObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"exclude\");\n  }\n  [$finalize]() {\n    this[$content] = this[$content].trim().split(/\\s+/).filter(x => x && [\"calculate\", \"close\", \"enter\", \"exit\", \"initialize\", \"ready\", \"validate\"].includes(x));\n  }\n}\nclass ExcludeNS extends StringObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"excludeNS\");\n  }\n}\nclass FlipLabel extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"flipLabel\", [\"usePrinterSetting\", \"on\", \"off\"]);\n  }\n}\nclass config_FontInfo extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"fontInfo\", true);\n    this.embed = null;\n    this.map = null;\n    this.subsetBelow = null;\n    this.alwaysEmbed = new XFAObjectArray();\n    this.defaultTypeface = new XFAObjectArray();\n    this.neverEmbed = new XFAObjectArray();\n  }\n}\nclass FormFieldFilling extends Option01 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"formFieldFilling\");\n  }\n}\nclass GroupParent extends StringObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"groupParent\");\n  }\n}\nclass IfEmpty extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"ifEmpty\", [\"dataValue\", \"dataGroup\", \"ignore\", \"remove\"]);\n  }\n}\nclass IncludeXDPContent extends StringObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"includeXDPContent\");\n  }\n}\nclass IncrementalLoad extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"incrementalLoad\", [\"none\", \"forwardOnly\"]);\n  }\n}\nclass IncrementalMerge extends Option01 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"incrementalMerge\");\n  }\n}\nclass Interactive extends Option01 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"interactive\");\n  }\n}\nclass Jog extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"jog\", [\"usePrinterSetting\", \"none\", \"pageSet\"]);\n  }\n}\nclass LabelPrinter extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"labelPrinter\", true);\n    this.name = getStringOption(attributes.name, [\"zpl\", \"dpl\", \"ipl\", \"tcpl\"]);\n    this.batchOutput = null;\n    this.flipLabel = null;\n    this.fontInfo = null;\n    this.xdc = null;\n  }\n}\nclass Layout extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"layout\", [\"paginate\", \"panel\"]);\n  }\n}\nclass Level extends IntegerObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"level\", 0, n => n > 0);\n  }\n}\nclass Linearized extends Option01 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"linearized\");\n  }\n}\nclass Locale extends StringObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"locale\");\n  }\n}\nclass LocaleSet extends StringObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"localeSet\");\n  }\n}\nclass Log extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"log\", true);\n    this.mode = null;\n    this.threshold = null;\n    this.to = null;\n    this.uri = null;\n  }\n}\nclass MapElement extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"map\", true);\n    this.equate = new XFAObjectArray();\n    this.equateRange = new XFAObjectArray();\n  }\n}\nclass MediumInfo extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"mediumInfo\", true);\n    this.map = null;\n  }\n}\nclass config_Message extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"message\", true);\n    this.msgId = null;\n    this.severity = null;\n  }\n}\nclass Messaging extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"messaging\", true);\n    this.message = new XFAObjectArray();\n  }\n}\nclass Mode extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"mode\", [\"append\", \"overwrite\"]);\n  }\n}\nclass ModifyAnnots extends Option01 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"modifyAnnots\");\n  }\n}\nclass MsgId extends IntegerObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"msgId\", 1, n => n >= 1);\n  }\n}\nclass NameAttr extends StringObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"nameAttr\");\n  }\n}\nclass NeverEmbed extends ContentObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"neverEmbed\");\n  }\n}\nclass NumberOfCopies extends IntegerObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"numberOfCopies\", null, n => n >= 2 && n <= 5);\n  }\n}\nclass OpenAction extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"openAction\", true);\n    this.destination = null;\n  }\n}\nclass Output extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"output\", true);\n    this.to = null;\n    this.type = null;\n    this.uri = null;\n  }\n}\nclass OutputBin extends StringObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"outputBin\");\n  }\n}\nclass OutputXSL extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"outputXSL\", true);\n    this.uri = null;\n  }\n}\nclass Overprint extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"overprint\", [\"none\", \"both\", \"draw\", \"field\"]);\n  }\n}\nclass Packets extends StringObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"packets\");\n  }\n  [$finalize]() {\n    if (this[$content] === \"*\") {\n      return;\n    }\n    this[$content] = this[$content].trim().split(/\\s+/).filter(x => [\"config\", \"datasets\", \"template\", \"xfdf\", \"xslt\"].includes(x));\n  }\n}\nclass PageOffset extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"pageOffset\");\n    this.x = getInteger({\n      data: attributes.x,\n      defaultValue: \"useXDCSetting\",\n      validate: n => true\n    });\n    this.y = getInteger({\n      data: attributes.y,\n      defaultValue: \"useXDCSetting\",\n      validate: n => true\n    });\n  }\n}\nclass PageRange extends StringObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"pageRange\");\n  }\n  [$finalize]() {\n    const numbers = this[$content].trim().split(/\\s+/).map(x => parseInt(x, 10));\n    const ranges = [];\n    for (let i = 0, ii = numbers.length; i < ii; i += 2) {\n      ranges.push(numbers.slice(i, i + 2));\n    }\n    this[$content] = ranges;\n  }\n}\nclass Pagination extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"pagination\", [\"simplex\", \"duplexShortEdge\", \"duplexLongEdge\"]);\n  }\n}\nclass PaginationOverride extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"paginationOverride\", [\"none\", \"forceDuplex\", \"forceDuplexLongEdge\", \"forceDuplexShortEdge\", \"forceSimplex\"]);\n  }\n}\nclass Part extends IntegerObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"part\", 1, n => false);\n  }\n}\nclass Pcl extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"pcl\", true);\n    this.name = attributes.name || \"\";\n    this.batchOutput = null;\n    this.fontInfo = null;\n    this.jog = null;\n    this.mediumInfo = null;\n    this.outputBin = null;\n    this.pageOffset = null;\n    this.staple = null;\n    this.xdc = null;\n  }\n}\nclass Pdf extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"pdf\", true);\n    this.name = attributes.name || \"\";\n    this.adobeExtensionLevel = null;\n    this.batchOutput = null;\n    this.compression = null;\n    this.creator = null;\n    this.encryption = null;\n    this.fontInfo = null;\n    this.interactive = null;\n    this.linearized = null;\n    this.openAction = null;\n    this.pdfa = null;\n    this.producer = null;\n    this.renderPolicy = null;\n    this.scriptModel = null;\n    this.silentPrint = null;\n    this.submitFormat = null;\n    this.tagged = null;\n    this.version = null;\n    this.viewerPreferences = null;\n    this.xdc = null;\n  }\n}\nclass Pdfa extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"pdfa\", true);\n    this.amd = null;\n    this.conformance = null;\n    this.includeXDPContent = null;\n    this.part = null;\n  }\n}\nclass Permissions extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"permissions\", true);\n    this.accessibleContent = null;\n    this.change = null;\n    this.contentCopy = null;\n    this.documentAssembly = null;\n    this.formFieldFilling = null;\n    this.modifyAnnots = null;\n    this.plaintextMetadata = null;\n    this.print = null;\n    this.printHighQuality = null;\n  }\n}\nclass PickTrayByPDFSize extends Option01 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"pickTrayByPDFSize\");\n  }\n}\nclass config_Picture extends StringObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"picture\");\n  }\n}\nclass PlaintextMetadata extends Option01 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"plaintextMetadata\");\n  }\n}\nclass Presence extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"presence\", [\"preserve\", \"dissolve\", \"dissolveStructure\", \"ignore\", \"remove\"]);\n  }\n}\nclass Present extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"present\", true);\n    this.behaviorOverride = null;\n    this.cache = null;\n    this.common = null;\n    this.copies = null;\n    this.destination = null;\n    this.incrementalMerge = null;\n    this.layout = null;\n    this.output = null;\n    this.overprint = null;\n    this.pagination = null;\n    this.paginationOverride = null;\n    this.script = null;\n    this.validate = null;\n    this.xdp = null;\n    this.driver = new XFAObjectArray();\n    this.labelPrinter = new XFAObjectArray();\n    this.pcl = new XFAObjectArray();\n    this.pdf = new XFAObjectArray();\n    this.ps = new XFAObjectArray();\n    this.submitUrl = new XFAObjectArray();\n    this.webClient = new XFAObjectArray();\n    this.zpl = new XFAObjectArray();\n  }\n}\nclass Print extends Option01 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"print\");\n  }\n}\nclass PrintHighQuality extends Option01 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"printHighQuality\");\n  }\n}\nclass PrintScaling extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"printScaling\", [\"appdefault\", \"noScaling\"]);\n  }\n}\nclass PrinterName extends StringObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"printerName\");\n  }\n}\nclass Producer extends StringObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"producer\");\n  }\n}\nclass Ps extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"ps\", true);\n    this.name = attributes.name || \"\";\n    this.batchOutput = null;\n    this.fontInfo = null;\n    this.jog = null;\n    this.mediumInfo = null;\n    this.outputBin = null;\n    this.staple = null;\n    this.xdc = null;\n  }\n}\nclass Range extends ContentObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"range\");\n  }\n  [$finalize]() {\n    this[$content] = this[$content].trim().split(/\\s*,\\s*/, 2).map(range => range.split(\"-\").map(x => parseInt(x.trim(), 10))).filter(range => range.every(x => !isNaN(x))).map(range => {\n      if (range.length === 1) {\n        range.push(range[0]);\n      }\n      return range;\n    });\n  }\n}\nclass Record extends ContentObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"record\");\n  }\n  [$finalize]() {\n    this[$content] = this[$content].trim();\n    const n = parseInt(this[$content], 10);\n    if (!isNaN(n) && n >= 0) {\n      this[$content] = n;\n    }\n  }\n}\nclass Relevant extends ContentObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"relevant\");\n  }\n  [$finalize]() {\n    this[$content] = this[$content].trim().split(/\\s+/);\n  }\n}\nclass Rename extends ContentObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"rename\");\n  }\n  [$finalize]() {\n    this[$content] = this[$content].trim();\n    if (this[$content].toLowerCase().startsWith(\"xml\") || new RegExp(\"[\\\\p{L}_][\\\\p{L}\\\\d._\\\\p{M}-]*\", \"u\").test(this[$content])) {\n      warn(\"XFA - Rename: invalid XFA name\");\n    }\n  }\n}\nclass RenderPolicy extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"renderPolicy\", [\"server\", \"client\"]);\n  }\n}\nclass RunScripts extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"runScripts\", [\"both\", \"client\", \"none\", \"server\"]);\n  }\n}\nclass config_Script extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"script\", true);\n    this.currentPage = null;\n    this.exclude = null;\n    this.runScripts = null;\n  }\n}\nclass ScriptModel extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"scriptModel\", [\"XFA\", \"none\"]);\n  }\n}\nclass Severity extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"severity\", [\"ignore\", \"error\", \"information\", \"trace\", \"warning\"]);\n  }\n}\nclass SilentPrint extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"silentPrint\", true);\n    this.addSilentPrint = null;\n    this.printerName = null;\n  }\n}\nclass Staple extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"staple\");\n    this.mode = getStringOption(attributes.mode, [\"usePrinterSetting\", \"on\", \"off\"]);\n  }\n}\nclass StartNode extends StringObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"startNode\");\n  }\n}\nclass StartPage extends IntegerObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"startPage\", 0, n => true);\n  }\n}\nclass SubmitFormat extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"submitFormat\", [\"html\", \"delegate\", \"fdf\", \"xml\", \"pdf\"]);\n  }\n}\nclass SubmitUrl extends StringObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"submitUrl\");\n  }\n}\nclass SubsetBelow extends IntegerObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"subsetBelow\", 100, n => n >= 0 && n <= 100);\n  }\n}\nclass SuppressBanner extends Option01 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"suppressBanner\");\n  }\n}\nclass Tagged extends Option01 {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"tagged\");\n  }\n}\nclass config_Template extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"template\", true);\n    this.base = null;\n    this.relevant = null;\n    this.startPage = null;\n    this.uri = null;\n    this.xsl = null;\n  }\n}\nclass Threshold extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"threshold\", [\"trace\", \"error\", \"information\", \"warning\"]);\n  }\n}\nclass To extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"to\", [\"null\", \"memory\", \"stderr\", \"stdout\", \"system\", \"uri\"]);\n  }\n}\nclass TemplateCache extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"templateCache\");\n    this.maxEntries = getInteger({\n      data: attributes.maxEntries,\n      defaultValue: 5,\n      validate: n => n >= 0\n    });\n  }\n}\nclass Trace extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"trace\", true);\n    this.area = new XFAObjectArray();\n  }\n}\nclass Transform extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"transform\", true);\n    this.groupParent = null;\n    this.ifEmpty = null;\n    this.nameAttr = null;\n    this.picture = null;\n    this.presence = null;\n    this.rename = null;\n    this.whitespace = null;\n  }\n}\nclass Type extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"type\", [\"none\", \"ascii85\", \"asciiHex\", \"ccittfax\", \"flate\", \"lzw\", \"runLength\", \"native\", \"xdp\", \"mergedXDP\"]);\n  }\n}\nclass Uri extends StringObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"uri\");\n  }\n}\nclass config_Validate extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"validate\", [\"preSubmit\", \"prePrint\", \"preExecute\", \"preSave\"]);\n  }\n}\nclass ValidateApprovalSignatures extends ContentObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"validateApprovalSignatures\");\n  }\n  [$finalize]() {\n    this[$content] = this[$content].trim().split(/\\s+/).filter(x => [\"docReady\", \"postSign\"].includes(x));\n  }\n}\nclass ValidationMessaging extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"validationMessaging\", [\"allMessagesIndividually\", \"allMessagesTogether\", \"firstMessageOnly\", \"noMessages\"]);\n  }\n}\nclass Version extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"version\", [\"1.7\", \"1.6\", \"1.5\", \"1.4\", \"1.3\", \"1.2\"]);\n  }\n}\nclass VersionControl extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"VersionControl\");\n    this.outputBelow = getStringOption(attributes.outputBelow, [\"warn\", \"error\", \"update\"]);\n    this.sourceAbove = getStringOption(attributes.sourceAbove, [\"warn\", \"error\"]);\n    this.sourceBelow = getStringOption(attributes.sourceBelow, [\"update\", \"maintain\"]);\n  }\n}\nclass ViewerPreferences extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"viewerPreferences\", true);\n    this.ADBE_JSConsole = null;\n    this.ADBE_JSDebugger = null;\n    this.addViewerPreferences = null;\n    this.duplexOption = null;\n    this.enforce = null;\n    this.numberOfCopies = null;\n    this.pageRange = null;\n    this.pickTrayByPDFSize = null;\n    this.printScaling = null;\n  }\n}\nclass WebClient extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"webClient\", true);\n    this.name = attributes.name ? attributes.name.trim() : \"\";\n    this.fontInfo = null;\n    this.xdc = null;\n  }\n}\nclass Whitespace extends OptionObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"whitespace\", [\"preserve\", \"ltrim\", \"normalize\", \"rtrim\", \"trim\"]);\n  }\n}\nclass Window extends ContentObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"window\");\n  }\n  [$finalize]() {\n    const pair = this[$content].trim().split(/\\s*,\\s*/, 2).map(x => parseInt(x, 10));\n    if (pair.some(x => isNaN(x))) {\n      this[$content] = [0, 0];\n      return;\n    }\n    if (pair.length === 1) {\n      pair.push(pair[0]);\n    }\n    this[$content] = pair;\n  }\n}\nclass Xdc extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"xdc\", true);\n    this.uri = new XFAObjectArray();\n    this.xsl = new XFAObjectArray();\n  }\n}\nclass Xdp extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"xdp\", true);\n    this.packets = null;\n  }\n}\nclass Xsl extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"xsl\", true);\n    this.debug = null;\n    this.uri = null;\n  }\n}\nclass Zpl extends XFAObject {\n  constructor(attributes) {\n    super(CONFIG_NS_ID, \"zpl\", true);\n    this.name = attributes.name ? attributes.name.trim() : \"\";\n    this.batchOutput = null;\n    this.flipLabel = null;\n    this.fontInfo = null;\n    this.xdc = null;\n  }\n}\nclass ConfigNamespace {\n  static [$buildXFAObject](name, attributes) {\n    if (ConfigNamespace.hasOwnProperty(name)) {\n      return ConfigNamespace[name](attributes);\n    }\n    return undefined;\n  }\n  static acrobat(attrs) {\n    return new Acrobat(attrs);\n  }\n  static acrobat7(attrs) {\n    return new Acrobat7(attrs);\n  }\n  static ADBE_JSConsole(attrs) {\n    return new ADBE_JSConsole(attrs);\n  }\n  static ADBE_JSDebugger(attrs) {\n    return new ADBE_JSDebugger(attrs);\n  }\n  static addSilentPrint(attrs) {\n    return new AddSilentPrint(attrs);\n  }\n  static addViewerPreferences(attrs) {\n    return new AddViewerPreferences(attrs);\n  }\n  static adjustData(attrs) {\n    return new AdjustData(attrs);\n  }\n  static adobeExtensionLevel(attrs) {\n    return new AdobeExtensionLevel(attrs);\n  }\n  static agent(attrs) {\n    return new Agent(attrs);\n  }\n  static alwaysEmbed(attrs) {\n    return new AlwaysEmbed(attrs);\n  }\n  static amd(attrs) {\n    return new Amd(attrs);\n  }\n  static area(attrs) {\n    return new config_Area(attrs);\n  }\n  static attributes(attrs) {\n    return new Attributes(attrs);\n  }\n  static autoSave(attrs) {\n    return new AutoSave(attrs);\n  }\n  static base(attrs) {\n    return new Base(attrs);\n  }\n  static batchOutput(attrs) {\n    return new BatchOutput(attrs);\n  }\n  static behaviorOverride(attrs) {\n    return new BehaviorOverride(attrs);\n  }\n  static cache(attrs) {\n    return new Cache(attrs);\n  }\n  static change(attrs) {\n    return new Change(attrs);\n  }\n  static common(attrs) {\n    return new Common(attrs);\n  }\n  static compress(attrs) {\n    return new Compress(attrs);\n  }\n  static compressLogicalStructure(attrs) {\n    return new CompressLogicalStructure(attrs);\n  }\n  static compressObjectStream(attrs) {\n    return new CompressObjectStream(attrs);\n  }\n  static compression(attrs) {\n    return new Compression(attrs);\n  }\n  static config(attrs) {\n    return new Config(attrs);\n  }\n  static conformance(attrs) {\n    return new Conformance(attrs);\n  }\n  static contentCopy(attrs) {\n    return new ContentCopy(attrs);\n  }\n  static copies(attrs) {\n    return new Copies(attrs);\n  }\n  static creator(attrs) {\n    return new Creator(attrs);\n  }\n  static currentPage(attrs) {\n    return new CurrentPage(attrs);\n  }\n  static data(attrs) {\n    return new Data(attrs);\n  }\n  static debug(attrs) {\n    return new Debug(attrs);\n  }\n  static defaultTypeface(attrs) {\n    return new DefaultTypeface(attrs);\n  }\n  static destination(attrs) {\n    return new Destination(attrs);\n  }\n  static documentAssembly(attrs) {\n    return new DocumentAssembly(attrs);\n  }\n  static driver(attrs) {\n    return new Driver(attrs);\n  }\n  static duplexOption(attrs) {\n    return new DuplexOption(attrs);\n  }\n  static dynamicRender(attrs) {\n    return new DynamicRender(attrs);\n  }\n  static embed(attrs) {\n    return new Embed(attrs);\n  }\n  static encrypt(attrs) {\n    return new config_Encrypt(attrs);\n  }\n  static encryption(attrs) {\n    return new config_Encryption(attrs);\n  }\n  static encryptionLevel(attrs) {\n    return new EncryptionLevel(attrs);\n  }\n  static enforce(attrs) {\n    return new Enforce(attrs);\n  }\n  static equate(attrs) {\n    return new Equate(attrs);\n  }\n  static equateRange(attrs) {\n    return new EquateRange(attrs);\n  }\n  static exclude(attrs) {\n    return new Exclude(attrs);\n  }\n  static excludeNS(attrs) {\n    return new ExcludeNS(attrs);\n  }\n  static flipLabel(attrs) {\n    return new FlipLabel(attrs);\n  }\n  static fontInfo(attrs) {\n    return new config_FontInfo(attrs);\n  }\n  static formFieldFilling(attrs) {\n    return new FormFieldFilling(attrs);\n  }\n  static groupParent(attrs) {\n    return new GroupParent(attrs);\n  }\n  static ifEmpty(attrs) {\n    return new IfEmpty(attrs);\n  }\n  static includeXDPContent(attrs) {\n    return new IncludeXDPContent(attrs);\n  }\n  static incrementalLoad(attrs) {\n    return new IncrementalLoad(attrs);\n  }\n  static incrementalMerge(attrs) {\n    return new IncrementalMerge(attrs);\n  }\n  static interactive(attrs) {\n    return new Interactive(attrs);\n  }\n  static jog(attrs) {\n    return new Jog(attrs);\n  }\n  static labelPrinter(attrs) {\n    return new LabelPrinter(attrs);\n  }\n  static layout(attrs) {\n    return new Layout(attrs);\n  }\n  static level(attrs) {\n    return new Level(attrs);\n  }\n  static linearized(attrs) {\n    return new Linearized(attrs);\n  }\n  static locale(attrs) {\n    return new Locale(attrs);\n  }\n  static localeSet(attrs) {\n    return new LocaleSet(attrs);\n  }\n  static log(attrs) {\n    return new Log(attrs);\n  }\n  static map(attrs) {\n    return new MapElement(attrs);\n  }\n  static mediumInfo(attrs) {\n    return new MediumInfo(attrs);\n  }\n  static message(attrs) {\n    return new config_Message(attrs);\n  }\n  static messaging(attrs) {\n    return new Messaging(attrs);\n  }\n  static mode(attrs) {\n    return new Mode(attrs);\n  }\n  static modifyAnnots(attrs) {\n    return new ModifyAnnots(attrs);\n  }\n  static msgId(attrs) {\n    return new MsgId(attrs);\n  }\n  static nameAttr(attrs) {\n    return new NameAttr(attrs);\n  }\n  static neverEmbed(attrs) {\n    return new NeverEmbed(attrs);\n  }\n  static numberOfCopies(attrs) {\n    return new NumberOfCopies(attrs);\n  }\n  static openAction(attrs) {\n    return new OpenAction(attrs);\n  }\n  static output(attrs) {\n    return new Output(attrs);\n  }\n  static outputBin(attrs) {\n    return new OutputBin(attrs);\n  }\n  static outputXSL(attrs) {\n    return new OutputXSL(attrs);\n  }\n  static overprint(attrs) {\n    return new Overprint(attrs);\n  }\n  static packets(attrs) {\n    return new Packets(attrs);\n  }\n  static pageOffset(attrs) {\n    return new PageOffset(attrs);\n  }\n  static pageRange(attrs) {\n    return new PageRange(attrs);\n  }\n  static pagination(attrs) {\n    return new Pagination(attrs);\n  }\n  static paginationOverride(attrs) {\n    return new PaginationOverride(attrs);\n  }\n  static part(attrs) {\n    return new Part(attrs);\n  }\n  static pcl(attrs) {\n    return new Pcl(attrs);\n  }\n  static pdf(attrs) {\n    return new Pdf(attrs);\n  }\n  static pdfa(attrs) {\n    return new Pdfa(attrs);\n  }\n  static permissions(attrs) {\n    return new Permissions(attrs);\n  }\n  static pickTrayByPDFSize(attrs) {\n    return new PickTrayByPDFSize(attrs);\n  }\n  static picture(attrs) {\n    return new config_Picture(attrs);\n  }\n  static plaintextMetadata(attrs) {\n    return new PlaintextMetadata(attrs);\n  }\n  static presence(attrs) {\n    return new Presence(attrs);\n  }\n  static present(attrs) {\n    return new Present(attrs);\n  }\n  static print(attrs) {\n    return new Print(attrs);\n  }\n  static printHighQuality(attrs) {\n    return new PrintHighQuality(attrs);\n  }\n  static printScaling(attrs) {\n    return new PrintScaling(attrs);\n  }\n  static printerName(attrs) {\n    return new PrinterName(attrs);\n  }\n  static producer(attrs) {\n    return new Producer(attrs);\n  }\n  static ps(attrs) {\n    return new Ps(attrs);\n  }\n  static range(attrs) {\n    return new Range(attrs);\n  }\n  static record(attrs) {\n    return new Record(attrs);\n  }\n  static relevant(attrs) {\n    return new Relevant(attrs);\n  }\n  static rename(attrs) {\n    return new Rename(attrs);\n  }\n  static renderPolicy(attrs) {\n    return new RenderPolicy(attrs);\n  }\n  static runScripts(attrs) {\n    return new RunScripts(attrs);\n  }\n  static script(attrs) {\n    return new config_Script(attrs);\n  }\n  static scriptModel(attrs) {\n    return new ScriptModel(attrs);\n  }\n  static severity(attrs) {\n    return new Severity(attrs);\n  }\n  static silentPrint(attrs) {\n    return new SilentPrint(attrs);\n  }\n  static staple(attrs) {\n    return new Staple(attrs);\n  }\n  static startNode(attrs) {\n    return new StartNode(attrs);\n  }\n  static startPage(attrs) {\n    return new StartPage(attrs);\n  }\n  static submitFormat(attrs) {\n    return new SubmitFormat(attrs);\n  }\n  static submitUrl(attrs) {\n    return new SubmitUrl(attrs);\n  }\n  static subsetBelow(attrs) {\n    return new SubsetBelow(attrs);\n  }\n  static suppressBanner(attrs) {\n    return new SuppressBanner(attrs);\n  }\n  static tagged(attrs) {\n    return new Tagged(attrs);\n  }\n  static template(attrs) {\n    return new config_Template(attrs);\n  }\n  static templateCache(attrs) {\n    return new TemplateCache(attrs);\n  }\n  static threshold(attrs) {\n    return new Threshold(attrs);\n  }\n  static to(attrs) {\n    return new To(attrs);\n  }\n  static trace(attrs) {\n    return new Trace(attrs);\n  }\n  static transform(attrs) {\n    return new Transform(attrs);\n  }\n  static type(attrs) {\n    return new Type(attrs);\n  }\n  static uri(attrs) {\n    return new Uri(attrs);\n  }\n  static validate(attrs) {\n    return new config_Validate(attrs);\n  }\n  static validateApprovalSignatures(attrs) {\n    return new ValidateApprovalSignatures(attrs);\n  }\n  static validationMessaging(attrs) {\n    return new ValidationMessaging(attrs);\n  }\n  static version(attrs) {\n    return new Version(attrs);\n  }\n  static versionControl(attrs) {\n    return new VersionControl(attrs);\n  }\n  static viewerPreferences(attrs) {\n    return new ViewerPreferences(attrs);\n  }\n  static webClient(attrs) {\n    return new WebClient(attrs);\n  }\n  static whitespace(attrs) {\n    return new Whitespace(attrs);\n  }\n  static window(attrs) {\n    return new Window(attrs);\n  }\n  static xdc(attrs) {\n    return new Xdc(attrs);\n  }\n  static xdp(attrs) {\n    return new Xdp(attrs);\n  }\n  static xsl(attrs) {\n    return new Xsl(attrs);\n  }\n  static zpl(attrs) {\n    return new Zpl(attrs);\n  }\n}\n\n;// ./src/core/xfa/connection_set.js\n\n\nconst CONNECTION_SET_NS_ID = NamespaceIds.connectionSet.id;\nclass ConnectionSet extends XFAObject {\n  constructor(attributes) {\n    super(CONNECTION_SET_NS_ID, \"connectionSet\", true);\n    this.wsdlConnection = new XFAObjectArray();\n    this.xmlConnection = new XFAObjectArray();\n    this.xsdConnection = new XFAObjectArray();\n  }\n}\nclass EffectiveInputPolicy extends XFAObject {\n  constructor(attributes) {\n    super(CONNECTION_SET_NS_ID, \"effectiveInputPolicy\");\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass EffectiveOutputPolicy extends XFAObject {\n  constructor(attributes) {\n    super(CONNECTION_SET_NS_ID, \"effectiveOutputPolicy\");\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass Operation extends StringObject {\n  constructor(attributes) {\n    super(CONNECTION_SET_NS_ID, \"operation\");\n    this.id = attributes.id || \"\";\n    this.input = attributes.input || \"\";\n    this.name = attributes.name || \"\";\n    this.output = attributes.output || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass RootElement extends StringObject {\n  constructor(attributes) {\n    super(CONNECTION_SET_NS_ID, \"rootElement\");\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass SoapAction extends StringObject {\n  constructor(attributes) {\n    super(CONNECTION_SET_NS_ID, \"soapAction\");\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass SoapAddress extends StringObject {\n  constructor(attributes) {\n    super(CONNECTION_SET_NS_ID, \"soapAddress\");\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass connection_set_Uri extends StringObject {\n  constructor(attributes) {\n    super(CONNECTION_SET_NS_ID, \"uri\");\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass WsdlAddress extends StringObject {\n  constructor(attributes) {\n    super(CONNECTION_SET_NS_ID, \"wsdlAddress\");\n    this.id = attributes.id || \"\";\n    this.name = attributes.name || \"\";\n    this.use = attributes.use || \"\";\n    this.usehref = attributes.usehref || \"\";\n  }\n}\nclass WsdlConnection extends XFAObject {\n  constructor(attributes) {\n    super(CONNECTION_SET_NS_ID, \"wsdlConnection\", true);\n    this.dataDescription = attributes.dataDescription || \"\";\n    this.name = attributes.name || \"\";\n    this.effectiveInputPolicy = null;\n    this.effectiveOutputPolicy = null;\n    this.operation = null;\n    this.soapAction = null;\n    this.soapAddress = null;\n    this.wsdlAddress = null;\n  }\n}\nclass XmlConnection extends XFAObject {\n  constructor(attributes) {\n    super(CONNECTION_SET_NS_ID, \"xmlConnection\", true);\n    this.dataDescription = attributes.dataDescription || \"\";\n    this.name = attributes.name || \"\";\n    this.uri = null;\n  }\n}\nclass XsdConnection extends XFAObject {\n  constructor(attributes) {\n    super(CONNECTION_SET_NS_ID, \"xsdConnection\", true);\n    this.dataDescription = attributes.dataDescription || \"\";\n    this.name = attributes.name || \"\";\n    this.rootElement = null;\n    this.uri = null;\n  }\n}\nclass ConnectionSetNamespace {\n  static [$buildXFAObject](name, attributes) {\n    if (ConnectionSetNamespace.hasOwnProperty(name)) {\n      return ConnectionSetNamespace[name](attributes);\n    }\n    return undefined;\n  }\n  static connectionSet(attrs) {\n    return new ConnectionSet(attrs);\n  }\n  static effectiveInputPolicy(attrs) {\n    return new EffectiveInputPolicy(attrs);\n  }\n  static effectiveOutputPolicy(attrs) {\n    return new EffectiveOutputPolicy(attrs);\n  }\n  static operation(attrs) {\n    return new Operation(attrs);\n  }\n  static rootElement(attrs) {\n    return new RootElement(attrs);\n  }\n  static soapAction(attrs) {\n    return new SoapAction(attrs);\n  }\n  static soapAddress(attrs) {\n    return new SoapAddress(attrs);\n  }\n  static uri(attrs) {\n    return new connection_set_Uri(attrs);\n  }\n  static wsdlAddress(attrs) {\n    return new WsdlAddress(attrs);\n  }\n  static wsdlConnection(attrs) {\n    return new WsdlConnection(attrs);\n  }\n  static xmlConnection(attrs) {\n    return new XmlConnection(attrs);\n  }\n  static xsdConnection(attrs) {\n    return new XsdConnection(attrs);\n  }\n}\n\n;// ./src/core/xfa/datasets.js\n\n\n\nconst DATASETS_NS_ID = NamespaceIds.datasets.id;\nclass datasets_Data extends XmlObject {\n  constructor(attributes) {\n    super(DATASETS_NS_ID, \"data\", attributes);\n  }\n  [$isNsAgnostic]() {\n    return true;\n  }\n}\nclass Datasets extends XFAObject {\n  constructor(attributes) {\n    super(DATASETS_NS_ID, \"datasets\", true);\n    this.data = null;\n    this.Signature = null;\n  }\n  [$onChild](child) {\n    const name = child[$nodeName];\n    if (name === \"data\" && child[$namespaceId] === DATASETS_NS_ID || name === \"Signature\" && child[$namespaceId] === NamespaceIds.signature.id) {\n      this[name] = child;\n    }\n    this[$appendChild](child);\n  }\n}\nclass DatasetsNamespace {\n  static [$buildXFAObject](name, attributes) {\n    if (DatasetsNamespace.hasOwnProperty(name)) {\n      return DatasetsNamespace[name](attributes);\n    }\n    return undefined;\n  }\n  static datasets(attributes) {\n    return new Datasets(attributes);\n  }\n  static data(attributes) {\n    return new datasets_Data(attributes);\n  }\n}\n\n;// ./src/core/xfa/locale_set.js\n\n\n\nconst LOCALE_SET_NS_ID = NamespaceIds.localeSet.id;\nclass CalendarSymbols extends XFAObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"calendarSymbols\", true);\n    this.name = \"gregorian\";\n    this.dayNames = new XFAObjectArray(2);\n    this.eraNames = null;\n    this.meridiemNames = null;\n    this.monthNames = new XFAObjectArray(2);\n  }\n}\nclass CurrencySymbol extends StringObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"currencySymbol\");\n    this.name = getStringOption(attributes.name, [\"symbol\", \"isoname\", \"decimal\"]);\n  }\n}\nclass CurrencySymbols extends XFAObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"currencySymbols\", true);\n    this.currencySymbol = new XFAObjectArray(3);\n  }\n}\nclass DatePattern extends StringObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"datePattern\");\n    this.name = getStringOption(attributes.name, [\"full\", \"long\", \"med\", \"short\"]);\n  }\n}\nclass DatePatterns extends XFAObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"datePatterns\", true);\n    this.datePattern = new XFAObjectArray(4);\n  }\n}\nclass DateTimeSymbols extends ContentObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"dateTimeSymbols\");\n  }\n}\nclass Day extends StringObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"day\");\n  }\n}\nclass DayNames extends XFAObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"dayNames\", true);\n    this.abbr = getInteger({\n      data: attributes.abbr,\n      defaultValue: 0,\n      validate: x => x === 1\n    });\n    this.day = new XFAObjectArray(7);\n  }\n}\nclass Era extends StringObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"era\");\n  }\n}\nclass EraNames extends XFAObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"eraNames\", true);\n    this.era = new XFAObjectArray(2);\n  }\n}\nclass locale_set_Locale extends XFAObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"locale\", true);\n    this.desc = attributes.desc || \"\";\n    this.name = \"isoname\";\n    this.calendarSymbols = null;\n    this.currencySymbols = null;\n    this.datePatterns = null;\n    this.dateTimeSymbols = null;\n    this.numberPatterns = null;\n    this.numberSymbols = null;\n    this.timePatterns = null;\n    this.typeFaces = null;\n  }\n}\nclass locale_set_LocaleSet extends XFAObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"localeSet\", true);\n    this.locale = new XFAObjectArray();\n  }\n}\nclass Meridiem extends StringObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"meridiem\");\n  }\n}\nclass MeridiemNames extends XFAObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"meridiemNames\", true);\n    this.meridiem = new XFAObjectArray(2);\n  }\n}\nclass Month extends StringObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"month\");\n  }\n}\nclass MonthNames extends XFAObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"monthNames\", true);\n    this.abbr = getInteger({\n      data: attributes.abbr,\n      defaultValue: 0,\n      validate: x => x === 1\n    });\n    this.month = new XFAObjectArray(12);\n  }\n}\nclass NumberPattern extends StringObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"numberPattern\");\n    this.name = getStringOption(attributes.name, [\"full\", \"long\", \"med\", \"short\"]);\n  }\n}\nclass NumberPatterns extends XFAObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"numberPatterns\", true);\n    this.numberPattern = new XFAObjectArray(4);\n  }\n}\nclass NumberSymbol extends StringObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"numberSymbol\");\n    this.name = getStringOption(attributes.name, [\"decimal\", \"grouping\", \"percent\", \"minus\", \"zero\"]);\n  }\n}\nclass NumberSymbols extends XFAObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"numberSymbols\", true);\n    this.numberSymbol = new XFAObjectArray(5);\n  }\n}\nclass TimePattern extends StringObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"timePattern\");\n    this.name = getStringOption(attributes.name, [\"full\", \"long\", \"med\", \"short\"]);\n  }\n}\nclass TimePatterns extends XFAObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"timePatterns\", true);\n    this.timePattern = new XFAObjectArray(4);\n  }\n}\nclass TypeFace extends XFAObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"typeFace\", true);\n    this.name = attributes.name | \"\";\n  }\n}\nclass TypeFaces extends XFAObject {\n  constructor(attributes) {\n    super(LOCALE_SET_NS_ID, \"typeFaces\", true);\n    this.typeFace = new XFAObjectArray();\n  }\n}\nclass LocaleSetNamespace {\n  static [$buildXFAObject](name, attributes) {\n    if (LocaleSetNamespace.hasOwnProperty(name)) {\n      return LocaleSetNamespace[name](attributes);\n    }\n    return undefined;\n  }\n  static calendarSymbols(attrs) {\n    return new CalendarSymbols(attrs);\n  }\n  static currencySymbol(attrs) {\n    return new CurrencySymbol(attrs);\n  }\n  static currencySymbols(attrs) {\n    return new CurrencySymbols(attrs);\n  }\n  static datePattern(attrs) {\n    return new DatePattern(attrs);\n  }\n  static datePatterns(attrs) {\n    return new DatePatterns(attrs);\n  }\n  static dateTimeSymbols(attrs) {\n    return new DateTimeSymbols(attrs);\n  }\n  static day(attrs) {\n    return new Day(attrs);\n  }\n  static dayNames(attrs) {\n    return new DayNames(attrs);\n  }\n  static era(attrs) {\n    return new Era(attrs);\n  }\n  static eraNames(attrs) {\n    return new EraNames(attrs);\n  }\n  static locale(attrs) {\n    return new locale_set_Locale(attrs);\n  }\n  static localeSet(attrs) {\n    return new locale_set_LocaleSet(attrs);\n  }\n  static meridiem(attrs) {\n    return new Meridiem(attrs);\n  }\n  static meridiemNames(attrs) {\n    return new MeridiemNames(attrs);\n  }\n  static month(attrs) {\n    return new Month(attrs);\n  }\n  static monthNames(attrs) {\n    return new MonthNames(attrs);\n  }\n  static numberPattern(attrs) {\n    return new NumberPattern(attrs);\n  }\n  static numberPatterns(attrs) {\n    return new NumberPatterns(attrs);\n  }\n  static numberSymbol(attrs) {\n    return new NumberSymbol(attrs);\n  }\n  static numberSymbols(attrs) {\n    return new NumberSymbols(attrs);\n  }\n  static timePattern(attrs) {\n    return new TimePattern(attrs);\n  }\n  static timePatterns(attrs) {\n    return new TimePatterns(attrs);\n  }\n  static typeFace(attrs) {\n    return new TypeFace(attrs);\n  }\n  static typeFaces(attrs) {\n    return new TypeFaces(attrs);\n  }\n}\n\n;// ./src/core/xfa/signature.js\n\n\nconst SIGNATURE_NS_ID = NamespaceIds.signature.id;\nclass signature_Signature extends XFAObject {\n  constructor(attributes) {\n    super(SIGNATURE_NS_ID, \"signature\", true);\n  }\n}\nclass SignatureNamespace {\n  static [$buildXFAObject](name, attributes) {\n    if (SignatureNamespace.hasOwnProperty(name)) {\n      return SignatureNamespace[name](attributes);\n    }\n    return undefined;\n  }\n  static signature(attributes) {\n    return new signature_Signature(attributes);\n  }\n}\n\n;// ./src/core/xfa/stylesheet.js\n\n\nconst STYLESHEET_NS_ID = NamespaceIds.stylesheet.id;\nclass Stylesheet extends XFAObject {\n  constructor(attributes) {\n    super(STYLESHEET_NS_ID, \"stylesheet\", true);\n  }\n}\nclass StylesheetNamespace {\n  static [$buildXFAObject](name, attributes) {\n    if (StylesheetNamespace.hasOwnProperty(name)) {\n      return StylesheetNamespace[name](attributes);\n    }\n    return undefined;\n  }\n  static stylesheet(attributes) {\n    return new Stylesheet(attributes);\n  }\n}\n\n;// ./src/core/xfa/xdp.js\n\n\n\nconst XDP_NS_ID = NamespaceIds.xdp.id;\nclass xdp_Xdp extends XFAObject {\n  constructor(attributes) {\n    super(XDP_NS_ID, \"xdp\", true);\n    this.uuid = attributes.uuid || \"\";\n    this.timeStamp = attributes.timeStamp || \"\";\n    this.config = null;\n    this.connectionSet = null;\n    this.datasets = null;\n    this.localeSet = null;\n    this.stylesheet = new XFAObjectArray();\n    this.template = null;\n  }\n  [$onChildCheck](child) {\n    const ns = NamespaceIds[child[$nodeName]];\n    return ns && child[$namespaceId] === ns.id;\n  }\n}\nclass XdpNamespace {\n  static [$buildXFAObject](name, attributes) {\n    if (XdpNamespace.hasOwnProperty(name)) {\n      return XdpNamespace[name](attributes);\n    }\n    return undefined;\n  }\n  static xdp(attributes) {\n    return new xdp_Xdp(attributes);\n  }\n}\n\n;// ./src/core/xfa/xhtml.js\n\n\n\n\n\nconst XHTML_NS_ID = NamespaceIds.xhtml.id;\nconst $richText = Symbol();\nconst VALID_STYLES = new Set([\"color\", \"font\", \"font-family\", \"font-size\", \"font-stretch\", \"font-style\", \"font-weight\", \"margin\", \"margin-bottom\", \"margin-left\", \"margin-right\", \"margin-top\", \"letter-spacing\", \"line-height\", \"orphans\", \"page-break-after\", \"page-break-before\", \"page-break-inside\", \"tab-interval\", \"tab-stop\", \"text-align\", \"text-decoration\", \"text-indent\", \"vertical-align\", \"widows\", \"kerning-mode\", \"xfa-font-horizontal-scale\", \"xfa-font-vertical-scale\", \"xfa-spacerun\", \"xfa-tab-stops\"]);\nconst StyleMapping = new Map([[\"page-break-after\", \"breakAfter\"], [\"page-break-before\", \"breakBefore\"], [\"page-break-inside\", \"breakInside\"], [\"kerning-mode\", value => value === \"none\" ? \"none\" : \"normal\"], [\"xfa-font-horizontal-scale\", value => `scaleX(${Math.max(0, Math.min(parseInt(value) / 100)).toFixed(2)})`], [\"xfa-font-vertical-scale\", value => `scaleY(${Math.max(0, Math.min(parseInt(value) / 100)).toFixed(2)})`], [\"xfa-spacerun\", \"\"], [\"xfa-tab-stops\", \"\"], [\"font-size\", (value, original) => {\n  value = original.fontSize = getMeasurement(value);\n  return measureToString(0.99 * value);\n}], [\"letter-spacing\", value => measureToString(getMeasurement(value))], [\"line-height\", value => measureToString(getMeasurement(value))], [\"margin\", value => measureToString(getMeasurement(value))], [\"margin-bottom\", value => measureToString(getMeasurement(value))], [\"margin-left\", value => measureToString(getMeasurement(value))], [\"margin-right\", value => measureToString(getMeasurement(value))], [\"margin-top\", value => measureToString(getMeasurement(value))], [\"text-indent\", value => measureToString(getMeasurement(value))], [\"font-family\", value => value], [\"vertical-align\", value => measureToString(getMeasurement(value))]]);\nconst spacesRegExp = /\\s+/g;\nconst crlfRegExp = /[\\r\\n]+/g;\nconst crlfForRichTextRegExp = /\\r\\n?/g;\nfunction mapStyle(styleStr, node, richText) {\n  const style = Object.create(null);\n  if (!styleStr) {\n    return style;\n  }\n  const original = Object.create(null);\n  for (const [key, value] of styleStr.split(\";\").map(s => s.split(\":\", 2))) {\n    const mapping = StyleMapping.get(key);\n    if (mapping === \"\") {\n      continue;\n    }\n    let newValue = value;\n    if (mapping) {\n      newValue = typeof mapping === \"string\" ? mapping : mapping(value, original);\n    }\n    if (key.endsWith(\"scale\")) {\n      style.transform = style.transform ? `${style[key]} ${newValue}` : newValue;\n    } else {\n      style[key.replaceAll(/-([a-zA-Z])/g, (_, x) => x.toUpperCase())] = newValue;\n    }\n  }\n  if (style.fontFamily) {\n    setFontFamily({\n      typeface: style.fontFamily,\n      weight: style.fontWeight || \"normal\",\n      posture: style.fontStyle || \"normal\",\n      size: original.fontSize || 0\n    }, node, node[$globalData].fontFinder, style);\n  }\n  if (richText && style.verticalAlign && style.verticalAlign !== \"0px\" && style.fontSize) {\n    const SUB_SUPER_SCRIPT_FACTOR = 0.583;\n    const VERTICAL_FACTOR = 0.333;\n    const fontSize = getMeasurement(style.fontSize);\n    style.fontSize = measureToString(fontSize * SUB_SUPER_SCRIPT_FACTOR);\n    style.verticalAlign = measureToString(Math.sign(getMeasurement(style.verticalAlign)) * fontSize * VERTICAL_FACTOR);\n  }\n  if (richText && style.fontSize) {\n    style.fontSize = `calc(${style.fontSize} * var(--scale-factor))`;\n  }\n  fixTextIndent(style);\n  return style;\n}\nfunction checkStyle(node) {\n  if (!node.style) {\n    return \"\";\n  }\n  return node.style.trim().split(/\\s*;\\s*/).filter(s => !!s).map(s => s.split(/\\s*:\\s*/, 2)).filter(([key, value]) => {\n    if (key === \"font-family\") {\n      node[$globalData].usedTypefaces.add(value);\n    }\n    return VALID_STYLES.has(key);\n  }).map(kv => kv.join(\":\")).join(\";\");\n}\nconst NoWhites = new Set([\"body\", \"html\"]);\nclass XhtmlObject extends XmlObject {\n  constructor(attributes, name) {\n    super(XHTML_NS_ID, name);\n    this[$richText] = false;\n    this.style = attributes.style || \"\";\n  }\n  [$clean](builder) {\n    super[$clean](builder);\n    this.style = checkStyle(this);\n  }\n  [$acceptWhitespace]() {\n    return !NoWhites.has(this[$nodeName]);\n  }\n  [$onText](str, richText = false) {\n    if (!richText) {\n      str = str.replaceAll(crlfRegExp, \"\");\n      if (!this.style.includes(\"xfa-spacerun:yes\")) {\n        str = str.replaceAll(spacesRegExp, \" \");\n      }\n    } else {\n      this[$richText] = true;\n    }\n    if (str) {\n      this[$content] += str;\n    }\n  }\n  [$pushGlyphs](measure, mustPop = true) {\n    const xfaFont = Object.create(null);\n    const margin = {\n      top: NaN,\n      bottom: NaN,\n      left: NaN,\n      right: NaN\n    };\n    let lineHeight = null;\n    for (const [key, value] of this.style.split(\";\").map(s => s.split(\":\", 2))) {\n      switch (key) {\n        case \"font-family\":\n          xfaFont.typeface = stripQuotes(value);\n          break;\n        case \"font-size\":\n          xfaFont.size = getMeasurement(value);\n          break;\n        case \"font-weight\":\n          xfaFont.weight = value;\n          break;\n        case \"font-style\":\n          xfaFont.posture = value;\n          break;\n        case \"letter-spacing\":\n          xfaFont.letterSpacing = getMeasurement(value);\n          break;\n        case \"margin\":\n          const values = value.split(/ \\t/).map(x => getMeasurement(x));\n          switch (values.length) {\n            case 1:\n              margin.top = margin.bottom = margin.left = margin.right = values[0];\n              break;\n            case 2:\n              margin.top = margin.bottom = values[0];\n              margin.left = margin.right = values[1];\n              break;\n            case 3:\n              margin.top = values[0];\n              margin.bottom = values[2];\n              margin.left = margin.right = values[1];\n              break;\n            case 4:\n              margin.top = values[0];\n              margin.left = values[1];\n              margin.bottom = values[2];\n              margin.right = values[3];\n              break;\n          }\n          break;\n        case \"margin-top\":\n          margin.top = getMeasurement(value);\n          break;\n        case \"margin-bottom\":\n          margin.bottom = getMeasurement(value);\n          break;\n        case \"margin-left\":\n          margin.left = getMeasurement(value);\n          break;\n        case \"margin-right\":\n          margin.right = getMeasurement(value);\n          break;\n        case \"line-height\":\n          lineHeight = getMeasurement(value);\n          break;\n      }\n    }\n    measure.pushData(xfaFont, margin, lineHeight);\n    if (this[$content]) {\n      measure.addString(this[$content]);\n    } else {\n      for (const child of this[$getChildren]()) {\n        if (child[$nodeName] === \"#text\") {\n          measure.addString(child[$content]);\n          continue;\n        }\n        child[$pushGlyphs](measure);\n      }\n    }\n    if (mustPop) {\n      measure.popFont();\n    }\n  }\n  [$toHTML](availableSpace) {\n    const children = [];\n    this[$extra] = {\n      children\n    };\n    this[$childrenToHTML]({});\n    if (children.length === 0 && !this[$content]) {\n      return HTMLResult.EMPTY;\n    }\n    let value;\n    if (this[$richText]) {\n      value = this[$content] ? this[$content].replaceAll(crlfForRichTextRegExp, \"\\n\") : undefined;\n    } else {\n      value = this[$content] || undefined;\n    }\n    return HTMLResult.success({\n      name: this[$nodeName],\n      attributes: {\n        href: this.href,\n        style: mapStyle(this.style, this, this[$richText])\n      },\n      children,\n      value\n    });\n  }\n}\nclass A extends XhtmlObject {\n  constructor(attributes) {\n    super(attributes, \"a\");\n    this.href = fixURL(attributes.href) || \"\";\n  }\n}\nclass B extends XhtmlObject {\n  constructor(attributes) {\n    super(attributes, \"b\");\n  }\n  [$pushGlyphs](measure) {\n    measure.pushFont({\n      weight: \"bold\"\n    });\n    super[$pushGlyphs](measure);\n    measure.popFont();\n  }\n}\nclass Body extends XhtmlObject {\n  constructor(attributes) {\n    super(attributes, \"body\");\n  }\n  [$toHTML](availableSpace) {\n    const res = super[$toHTML](availableSpace);\n    const {\n      html\n    } = res;\n    if (!html) {\n      return HTMLResult.EMPTY;\n    }\n    html.name = \"div\";\n    html.attributes.class = [\"xfaRich\"];\n    return res;\n  }\n}\nclass Br extends XhtmlObject {\n  constructor(attributes) {\n    super(attributes, \"br\");\n  }\n  [$text]() {\n    return \"\\n\";\n  }\n  [$pushGlyphs](measure) {\n    measure.addString(\"\\n\");\n  }\n  [$toHTML](availableSpace) {\n    return HTMLResult.success({\n      name: \"br\"\n    });\n  }\n}\nclass Html extends XhtmlObject {\n  constructor(attributes) {\n    super(attributes, \"html\");\n  }\n  [$toHTML](availableSpace) {\n    const children = [];\n    this[$extra] = {\n      children\n    };\n    this[$childrenToHTML]({});\n    if (children.length === 0) {\n      return HTMLResult.success({\n        name: \"div\",\n        attributes: {\n          class: [\"xfaRich\"],\n          style: {}\n        },\n        value: this[$content] || \"\"\n      });\n    }\n    if (children.length === 1) {\n      const child = children[0];\n      if (child.attributes?.class.includes(\"xfaRich\")) {\n        return HTMLResult.success(child);\n      }\n    }\n    return HTMLResult.success({\n      name: \"div\",\n      attributes: {\n        class: [\"xfaRich\"],\n        style: {}\n      },\n      children\n    });\n  }\n}\nclass I extends XhtmlObject {\n  constructor(attributes) {\n    super(attributes, \"i\");\n  }\n  [$pushGlyphs](measure) {\n    measure.pushFont({\n      posture: \"italic\"\n    });\n    super[$pushGlyphs](measure);\n    measure.popFont();\n  }\n}\nclass Li extends XhtmlObject {\n  constructor(attributes) {\n    super(attributes, \"li\");\n  }\n}\nclass Ol extends XhtmlObject {\n  constructor(attributes) {\n    super(attributes, \"ol\");\n  }\n}\nclass P extends XhtmlObject {\n  constructor(attributes) {\n    super(attributes, \"p\");\n  }\n  [$pushGlyphs](measure) {\n    super[$pushGlyphs](measure, false);\n    measure.addString(\"\\n\");\n    measure.addPara();\n    measure.popFont();\n  }\n  [$text]() {\n    const siblings = this[$getParent]()[$getChildren]();\n    if (siblings.at(-1) === this) {\n      return super[$text]();\n    }\n    return super[$text]() + \"\\n\";\n  }\n}\nclass Span extends XhtmlObject {\n  constructor(attributes) {\n    super(attributes, \"span\");\n  }\n}\nclass Sub extends XhtmlObject {\n  constructor(attributes) {\n    super(attributes, \"sub\");\n  }\n}\nclass Sup extends XhtmlObject {\n  constructor(attributes) {\n    super(attributes, \"sup\");\n  }\n}\nclass Ul extends XhtmlObject {\n  constructor(attributes) {\n    super(attributes, \"ul\");\n  }\n}\nclass XhtmlNamespace {\n  static [$buildXFAObject](name, attributes) {\n    if (XhtmlNamespace.hasOwnProperty(name)) {\n      return XhtmlNamespace[name](attributes);\n    }\n    return undefined;\n  }\n  static a(attributes) {\n    return new A(attributes);\n  }\n  static b(attributes) {\n    return new B(attributes);\n  }\n  static body(attributes) {\n    return new Body(attributes);\n  }\n  static br(attributes) {\n    return new Br(attributes);\n  }\n  static html(attributes) {\n    return new Html(attributes);\n  }\n  static i(attributes) {\n    return new I(attributes);\n  }\n  static li(attributes) {\n    return new Li(attributes);\n  }\n  static ol(attributes) {\n    return new Ol(attributes);\n  }\n  static p(attributes) {\n    return new P(attributes);\n  }\n  static span(attributes) {\n    return new Span(attributes);\n  }\n  static sub(attributes) {\n    return new Sub(attributes);\n  }\n  static sup(attributes) {\n    return new Sup(attributes);\n  }\n  static ul(attributes) {\n    return new Ul(attributes);\n  }\n}\n\n;// ./src/core/xfa/setup.js\n\n\n\n\n\n\n\n\n\nconst NamespaceSetUp = {\n  config: ConfigNamespace,\n  connection: ConnectionSetNamespace,\n  datasets: DatasetsNamespace,\n  localeSet: LocaleSetNamespace,\n  signature: SignatureNamespace,\n  stylesheet: StylesheetNamespace,\n  template: TemplateNamespace,\n  xdp: XdpNamespace,\n  xhtml: XhtmlNamespace\n};\n\n;// ./src/core/xfa/unknown.js\n\n\nclass UnknownNamespace {\n  constructor(nsId) {\n    this.namespaceId = nsId;\n  }\n  [$buildXFAObject](name, attributes) {\n    return new XmlObject(this.namespaceId, name, attributes);\n  }\n}\n\n;// ./src/core/xfa/builder.js\n\n\n\n\n\n\n\nclass Root extends XFAObject {\n  constructor(ids) {\n    super(-1, \"root\", Object.create(null));\n    this.element = null;\n    this[$ids] = ids;\n  }\n  [$onChild](child) {\n    this.element = child;\n    return true;\n  }\n  [$finalize]() {\n    super[$finalize]();\n    if (this.element.template instanceof Template) {\n      this[$ids].set($root, this.element);\n      this.element.template[$resolvePrototypes](this[$ids]);\n      this.element.template[$ids] = this[$ids];\n    }\n  }\n}\nclass Empty extends XFAObject {\n  constructor() {\n    super(-1, \"\", Object.create(null));\n  }\n  [$onChild](_) {\n    return false;\n  }\n}\nclass Builder {\n  constructor(rootNameSpace = null) {\n    this._namespaceStack = [];\n    this._nsAgnosticLevel = 0;\n    this._namespacePrefixes = new Map();\n    this._namespaces = new Map();\n    this._nextNsId = Math.max(...Object.values(NamespaceIds).map(({\n      id\n    }) => id));\n    this._currentNamespace = rootNameSpace || new UnknownNamespace(++this._nextNsId);\n  }\n  buildRoot(ids) {\n    return new Root(ids);\n  }\n  build({\n    nsPrefix,\n    name,\n    attributes,\n    namespace,\n    prefixes\n  }) {\n    const hasNamespaceDef = namespace !== null;\n    if (hasNamespaceDef) {\n      this._namespaceStack.push(this._currentNamespace);\n      this._currentNamespace = this._searchNamespace(namespace);\n    }\n    if (prefixes) {\n      this._addNamespacePrefix(prefixes);\n    }\n    if (attributes.hasOwnProperty($nsAttributes)) {\n      const dataTemplate = NamespaceSetUp.datasets;\n      const nsAttrs = attributes[$nsAttributes];\n      let xfaAttrs = null;\n      for (const [ns, attrs] of Object.entries(nsAttrs)) {\n        const nsToUse = this._getNamespaceToUse(ns);\n        if (nsToUse === dataTemplate) {\n          xfaAttrs = {\n            xfa: attrs\n          };\n          break;\n        }\n      }\n      if (xfaAttrs) {\n        attributes[$nsAttributes] = xfaAttrs;\n      } else {\n        delete attributes[$nsAttributes];\n      }\n    }\n    const namespaceToUse = this._getNamespaceToUse(nsPrefix);\n    const node = namespaceToUse?.[$buildXFAObject](name, attributes) || new Empty();\n    if (node[$isNsAgnostic]()) {\n      this._nsAgnosticLevel++;\n    }\n    if (hasNamespaceDef || prefixes || node[$isNsAgnostic]()) {\n      node[$cleanup] = {\n        hasNamespace: hasNamespaceDef,\n        prefixes,\n        nsAgnostic: node[$isNsAgnostic]()\n      };\n    }\n    return node;\n  }\n  isNsAgnostic() {\n    return this._nsAgnosticLevel > 0;\n  }\n  _searchNamespace(nsName) {\n    let ns = this._namespaces.get(nsName);\n    if (ns) {\n      return ns;\n    }\n    for (const [name, {\n      check\n    }] of Object.entries(NamespaceIds)) {\n      if (check(nsName)) {\n        ns = NamespaceSetUp[name];\n        if (ns) {\n          this._namespaces.set(nsName, ns);\n          return ns;\n        }\n        break;\n      }\n    }\n    ns = new UnknownNamespace(++this._nextNsId);\n    this._namespaces.set(nsName, ns);\n    return ns;\n  }\n  _addNamespacePrefix(prefixes) {\n    for (const {\n      prefix,\n      value\n    } of prefixes) {\n      const namespace = this._searchNamespace(value);\n      let prefixStack = this._namespacePrefixes.get(prefix);\n      if (!prefixStack) {\n        prefixStack = [];\n        this._namespacePrefixes.set(prefix, prefixStack);\n      }\n      prefixStack.push(namespace);\n    }\n  }\n  _getNamespaceToUse(prefix) {\n    if (!prefix) {\n      return this._currentNamespace;\n    }\n    const prefixStack = this._namespacePrefixes.get(prefix);\n    if (prefixStack?.length > 0) {\n      return prefixStack.at(-1);\n    }\n    warn(`Unknown namespace prefix: ${prefix}.`);\n    return null;\n  }\n  clean(data) {\n    const {\n      hasNamespace,\n      prefixes,\n      nsAgnostic\n    } = data;\n    if (hasNamespace) {\n      this._currentNamespace = this._namespaceStack.pop();\n    }\n    if (prefixes) {\n      prefixes.forEach(({\n        prefix\n      }) => {\n        this._namespacePrefixes.get(prefix).pop();\n      });\n    }\n    if (nsAgnostic) {\n      this._nsAgnosticLevel--;\n    }\n  }\n}\n\n;// ./src/core/xfa/parser.js\n\n\n\n\nclass XFAParser extends XMLParserBase {\n  constructor(rootNameSpace = null, richText = false) {\n    super();\n    this._builder = new Builder(rootNameSpace);\n    this._stack = [];\n    this._globalData = {\n      usedTypefaces: new Set()\n    };\n    this._ids = new Map();\n    this._current = this._builder.buildRoot(this._ids);\n    this._errorCode = XMLParserErrorCode.NoError;\n    this._whiteRegex = /^\\s+$/;\n    this._nbsps = /\\xa0+/g;\n    this._richText = richText;\n  }\n  parse(data) {\n    this.parseXml(data);\n    if (this._errorCode !== XMLParserErrorCode.NoError) {\n      return undefined;\n    }\n    this._current[$finalize]();\n    return this._current.element;\n  }\n  onText(text) {\n    text = text.replace(this._nbsps, match => match.slice(1) + \" \");\n    if (this._richText || this._current[$acceptWhitespace]()) {\n      this._current[$onText](text, this._richText);\n      return;\n    }\n    if (this._whiteRegex.test(text)) {\n      return;\n    }\n    this._current[$onText](text.trim());\n  }\n  onCdata(text) {\n    this._current[$onText](text);\n  }\n  _mkAttributes(attributes, tagName) {\n    let namespace = null;\n    let prefixes = null;\n    const attributeObj = Object.create({});\n    for (const {\n      name,\n      value\n    } of attributes) {\n      if (name === \"xmlns\") {\n        if (!namespace) {\n          namespace = value;\n        } else {\n          warn(`XFA - multiple namespace definition in <${tagName}>`);\n        }\n      } else if (name.startsWith(\"xmlns:\")) {\n        const prefix = name.substring(\"xmlns:\".length);\n        if (!prefixes) {\n          prefixes = [];\n        }\n        prefixes.push({\n          prefix,\n          value\n        });\n      } else {\n        const i = name.indexOf(\":\");\n        if (i === -1) {\n          attributeObj[name] = value;\n        } else {\n          let nsAttrs = attributeObj[$nsAttributes];\n          if (!nsAttrs) {\n            nsAttrs = attributeObj[$nsAttributes] = Object.create(null);\n          }\n          const [ns, attrName] = [name.slice(0, i), name.slice(i + 1)];\n          const attrs = nsAttrs[ns] ||= Object.create(null);\n          attrs[attrName] = value;\n        }\n      }\n    }\n    return [namespace, prefixes, attributeObj];\n  }\n  _getNameAndPrefix(name, nsAgnostic) {\n    const i = name.indexOf(\":\");\n    if (i === -1) {\n      return [name, null];\n    }\n    return [name.substring(i + 1), nsAgnostic ? \"\" : name.substring(0, i)];\n  }\n  onBeginElement(tagName, attributes, isEmpty) {\n    const [namespace, prefixes, attributesObj] = this._mkAttributes(attributes, tagName);\n    const [name, nsPrefix] = this._getNameAndPrefix(tagName, this._builder.isNsAgnostic());\n    const node = this._builder.build({\n      nsPrefix,\n      name,\n      attributes: attributesObj,\n      namespace,\n      prefixes\n    });\n    node[$globalData] = this._globalData;\n    if (isEmpty) {\n      node[$finalize]();\n      if (this._current[$onChild](node)) {\n        node[$setId](this._ids);\n      }\n      node[$clean](this._builder);\n      return;\n    }\n    this._stack.push(this._current);\n    this._current = node;\n  }\n  onEndElement(name) {\n    const node = this._current;\n    if (node[$isCDATAXml]() && typeof node[$content] === \"string\") {\n      const parser = new XFAParser();\n      parser._globalData = this._globalData;\n      const root = parser.parse(node[$content]);\n      node[$content] = null;\n      node[$onChild](root);\n    }\n    node[$finalize]();\n    this._current = this._stack.pop();\n    if (this._current[$onChild](node)) {\n      node[$setId](this._ids);\n    }\n    node[$clean](this._builder);\n  }\n  onError(code) {\n    this._errorCode = code;\n  }\n}\n\n;// ./src/core/xfa/factory.js\n\n\n\n\n\n\n\n\nclass XFAFactory {\n  constructor(data) {\n    try {\n      this.root = new XFAParser().parse(XFAFactory._createDocument(data));\n      const binder = new Binder(this.root);\n      this.form = binder.bind();\n      this.dataHandler = new DataHandler(this.root, binder.getData());\n      this.form[$globalData].template = this.form;\n    } catch (e) {\n      warn(`XFA - an error occurred during parsing and binding: ${e}`);\n    }\n  }\n  isValid() {\n    return this.root && this.form;\n  }\n  _createPagesHelper() {\n    const iterator = this.form[$toPages]();\n    return new Promise((resolve, reject) => {\n      const nextIteration = () => {\n        try {\n          const value = iterator.next();\n          if (value.done) {\n            resolve(value.value);\n          } else {\n            setTimeout(nextIteration, 0);\n          }\n        } catch (e) {\n          reject(e);\n        }\n      };\n      setTimeout(nextIteration, 0);\n    });\n  }\n  async _createPages() {\n    try {\n      this.pages = await this._createPagesHelper();\n      this.dims = this.pages.children.map(c => {\n        const {\n          width,\n          height\n        } = c.attributes.style;\n        return [0, 0, parseInt(width), parseInt(height)];\n      });\n    } catch (e) {\n      warn(`XFA - an error occurred during layout: ${e}`);\n    }\n  }\n  getBoundingBox(pageIndex) {\n    return this.dims[pageIndex];\n  }\n  async getNumPages() {\n    if (!this.pages) {\n      await this._createPages();\n    }\n    return this.dims.length;\n  }\n  setImages(images) {\n    this.form[$globalData].images = images;\n  }\n  setFonts(fonts) {\n    this.form[$globalData].fontFinder = new FontFinder(fonts);\n    const missingFonts = [];\n    for (let typeface of this.form[$globalData].usedTypefaces) {\n      typeface = stripQuotes(typeface);\n      const font = this.form[$globalData].fontFinder.find(typeface);\n      if (!font) {\n        missingFonts.push(typeface);\n      }\n    }\n    if (missingFonts.length > 0) {\n      return missingFonts;\n    }\n    return null;\n  }\n  appendFonts(fonts, reallyMissingFonts) {\n    this.form[$globalData].fontFinder.add(fonts, reallyMissingFonts);\n  }\n  async getPages() {\n    if (!this.pages) {\n      await this._createPages();\n    }\n    const pages = this.pages;\n    this.pages = null;\n    return pages;\n  }\n  serializeData(storage) {\n    return this.dataHandler.serialize(storage);\n  }\n  static _createDocument(data) {\n    if (!data[\"/xdp:xdp\"]) {\n      return data[\"xdp:xdp\"];\n    }\n    return Object.values(data).join(\"\");\n  }\n  static getRichTextAsHtml(rc) {\n    if (!rc || typeof rc !== \"string\") {\n      return null;\n    }\n    try {\n      let root = new XFAParser(XhtmlNamespace, true).parse(rc);\n      if (![\"body\", \"xhtml\"].includes(root[$nodeName])) {\n        const newRoot = XhtmlNamespace.body({});\n        newRoot[$appendChild](root);\n        root = newRoot;\n      }\n      const result = root[$toHTML]();\n      if (!result.success) {\n        return null;\n      }\n      const {\n        html\n      } = result;\n      const {\n        attributes\n      } = html;\n      if (attributes) {\n        if (attributes.class) {\n          attributes.class = attributes.class.filter(attr => !attr.startsWith(\"xfa\"));\n        }\n        attributes.dir = \"auto\";\n      }\n      return {\n        html,\n        str: root[$text]()\n      };\n    } catch (e) {\n      warn(`XFA - an error occurred during parsing of rich text: ${e}`);\n    }\n    return null;\n  }\n}\n\n;// ./src/core/annotation.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nclass AnnotationFactory {\n  static createGlobals(pdfManager) {\n    return Promise.all([pdfManager.ensureCatalog(\"acroForm\"), pdfManager.ensureDoc(\"xfaDatasets\"), pdfManager.ensureCatalog(\"structTreeRoot\"), pdfManager.ensureCatalog(\"baseUrl\"), pdfManager.ensureCatalog(\"attachments\")]).then(([acroForm, xfaDatasets, structTreeRoot, baseUrl, attachments]) => {\n      return {\n        pdfManager,\n        acroForm: acroForm instanceof Dict ? acroForm : Dict.empty,\n        xfaDatasets,\n        structTreeRoot,\n        baseUrl,\n        attachments\n      };\n    }, reason => {\n      warn(`createGlobals: \"${reason}\".`);\n      return null;\n    });\n  }\n  static async create(xref, ref, annotationGlobals, idFactory, collectFields, pageRef) {\n    const pageIndex = collectFields ? await this._getPageIndex(xref, ref, annotationGlobals.pdfManager) : null;\n    return annotationGlobals.pdfManager.ensure(this, \"_create\", [xref, ref, annotationGlobals, idFactory, collectFields, pageIndex, pageRef]);\n  }\n  static _create(xref, ref, annotationGlobals, idFactory, collectFields = false, pageIndex = null, pageRef = null) {\n    const dict = xref.fetchIfRef(ref);\n    if (!(dict instanceof Dict)) {\n      return undefined;\n    }\n    const {\n      acroForm,\n      pdfManager\n    } = annotationGlobals;\n    const id = ref instanceof Ref ? ref.toString() : `annot_${idFactory.createObjId()}`;\n    let subtype = dict.get(\"Subtype\");\n    subtype = subtype instanceof Name ? subtype.name : null;\n    const parameters = {\n      xref,\n      ref,\n      dict,\n      subtype,\n      id,\n      annotationGlobals,\n      collectFields,\n      needAppearances: !collectFields && acroForm.get(\"NeedAppearances\") === true,\n      pageIndex,\n      evaluatorOptions: pdfManager.evaluatorOptions,\n      pageRef\n    };\n    switch (subtype) {\n      case \"Link\":\n        return new LinkAnnotation(parameters);\n      case \"Text\":\n        return new TextAnnotation(parameters);\n      case \"Widget\":\n        let fieldType = getInheritableProperty({\n          dict,\n          key: \"FT\"\n        });\n        fieldType = fieldType instanceof Name ? fieldType.name : null;\n        switch (fieldType) {\n          case \"Tx\":\n            return new TextWidgetAnnotation(parameters);\n          case \"Btn\":\n            return new ButtonWidgetAnnotation(parameters);\n          case \"Ch\":\n            return new ChoiceWidgetAnnotation(parameters);\n          case \"Sig\":\n            return new SignatureWidgetAnnotation(parameters);\n        }\n        warn(`Unimplemented widget field type \"${fieldType}\", ` + \"falling back to base field type.\");\n        return new WidgetAnnotation(parameters);\n      case \"Popup\":\n        return new PopupAnnotation(parameters);\n      case \"FreeText\":\n        return new FreeTextAnnotation(parameters);\n      case \"Line\":\n        return new LineAnnotation(parameters);\n      case \"Square\":\n        return new SquareAnnotation(parameters);\n      case \"Circle\":\n        return new CircleAnnotation(parameters);\n      case \"PolyLine\":\n        return new PolylineAnnotation(parameters);\n      case \"Polygon\":\n        return new PolygonAnnotation(parameters);\n      case \"Caret\":\n        return new CaretAnnotation(parameters);\n      case \"Ink\":\n        return new InkAnnotation(parameters);\n      case \"Highlight\":\n        return new HighlightAnnotation(parameters);\n      case \"Underline\":\n        return new UnderlineAnnotation(parameters);\n      case \"Squiggly\":\n        return new SquigglyAnnotation(parameters);\n      case \"StrikeOut\":\n        return new StrikeOutAnnotation(parameters);\n      case \"Stamp\":\n        return new StampAnnotation(parameters);\n      case \"FileAttachment\":\n        return new FileAttachmentAnnotation(parameters);\n      default:\n        if (!collectFields) {\n          if (!subtype) {\n            warn(\"Annotation is missing the required /Subtype.\");\n          } else {\n            warn(`Unimplemented annotation type \"${subtype}\", ` + \"falling back to base annotation.\");\n          }\n        }\n        return new Annotation(parameters);\n    }\n  }\n  static async _getPageIndex(xref, ref, pdfManager) {\n    try {\n      const annotDict = await xref.fetchIfRefAsync(ref);\n      if (!(annotDict instanceof Dict)) {\n        return -1;\n      }\n      const pageRef = annotDict.getRaw(\"P\");\n      if (pageRef instanceof Ref) {\n        try {\n          const pageIndex = await pdfManager.ensureCatalog(\"getPageIndex\", [pageRef]);\n          return pageIndex;\n        } catch (ex) {\n          info(`_getPageIndex -- not a valid page reference: \"${ex}\".`);\n        }\n      }\n      if (annotDict.has(\"Kids\")) {\n        return -1;\n      }\n      const numPages = await pdfManager.ensureDoc(\"numPages\");\n      for (let pageIndex = 0; pageIndex < numPages; pageIndex++) {\n        const page = await pdfManager.getPage(pageIndex);\n        const annotations = await pdfManager.ensure(page, \"annotations\");\n        for (const annotRef of annotations) {\n          if (annotRef instanceof Ref && isRefsEqual(annotRef, ref)) {\n            return pageIndex;\n          }\n        }\n      }\n    } catch (ex) {\n      warn(`_getPageIndex: \"${ex}\".`);\n    }\n    return -1;\n  }\n  static generateImages(annotations, xref, isOffscreenCanvasSupported) {\n    if (!isOffscreenCanvasSupported) {\n      warn(\"generateImages: OffscreenCanvas is not supported, cannot save or print some annotations with images.\");\n      return null;\n    }\n    let imagePromises;\n    for (const {\n      bitmapId,\n      bitmap\n    } of annotations) {\n      if (!bitmap) {\n        continue;\n      }\n      imagePromises ||= new Map();\n      imagePromises.set(bitmapId, StampAnnotation.createImage(bitmap, xref));\n    }\n    return imagePromises;\n  }\n  static async saveNewAnnotations(evaluator, task, annotations, imagePromises) {\n    const xref = evaluator.xref;\n    let baseFontRef;\n    const dependencies = [];\n    const promises = [];\n    const {\n      isOffscreenCanvasSupported\n    } = evaluator.options;\n    for (const annotation of annotations) {\n      if (annotation.deleted) {\n        continue;\n      }\n      switch (annotation.annotationType) {\n        case AnnotationEditorType.FREETEXT:\n          if (!baseFontRef) {\n            const baseFont = new Dict(xref);\n            baseFont.set(\"BaseFont\", Name.get(\"Helvetica\"));\n            baseFont.set(\"Type\", Name.get(\"Font\"));\n            baseFont.set(\"Subtype\", Name.get(\"Type1\"));\n            baseFont.set(\"Encoding\", Name.get(\"WinAnsiEncoding\"));\n            const buffer = [];\n            baseFontRef = xref.getNewTemporaryRef();\n            await writeObject(baseFontRef, baseFont, buffer, xref);\n            dependencies.push({\n              ref: baseFontRef,\n              data: buffer.join(\"\")\n            });\n          }\n          promises.push(FreeTextAnnotation.createNewAnnotation(xref, annotation, dependencies, {\n            evaluator,\n            task,\n            baseFontRef\n          }));\n          break;\n        case AnnotationEditorType.HIGHLIGHT:\n          if (annotation.quadPoints) {\n            promises.push(HighlightAnnotation.createNewAnnotation(xref, annotation, dependencies));\n          } else {\n            promises.push(InkAnnotation.createNewAnnotation(xref, annotation, dependencies));\n          }\n          break;\n        case AnnotationEditorType.INK:\n          promises.push(InkAnnotation.createNewAnnotation(xref, annotation, dependencies));\n          break;\n        case AnnotationEditorType.STAMP:\n          if (!isOffscreenCanvasSupported) {\n            break;\n          }\n          const image = await imagePromises.get(annotation.bitmapId);\n          if (image.imageStream) {\n            const {\n              imageStream,\n              smaskStream\n            } = image;\n            const buffer = [];\n            if (smaskStream) {\n              const smaskRef = xref.getNewTemporaryRef();\n              await writeObject(smaskRef, smaskStream, buffer, xref);\n              dependencies.push({\n                ref: smaskRef,\n                data: buffer.join(\"\")\n              });\n              imageStream.dict.set(\"SMask\", smaskRef);\n              buffer.length = 0;\n            }\n            const imageRef = image.imageRef = xref.getNewTemporaryRef();\n            await writeObject(imageRef, imageStream, buffer, xref);\n            dependencies.push({\n              ref: imageRef,\n              data: buffer.join(\"\")\n            });\n            image.imageStream = image.smaskStream = null;\n          }\n          promises.push(StampAnnotation.createNewAnnotation(xref, annotation, dependencies, {\n            image\n          }));\n          break;\n      }\n    }\n    return {\n      annotations: await Promise.all(promises),\n      dependencies\n    };\n  }\n  static async printNewAnnotations(annotationGlobals, evaluator, task, annotations, imagePromises) {\n    if (!annotations) {\n      return null;\n    }\n    const {\n      options,\n      xref\n    } = evaluator;\n    const promises = [];\n    for (const annotation of annotations) {\n      if (annotation.deleted) {\n        continue;\n      }\n      switch (annotation.annotationType) {\n        case AnnotationEditorType.FREETEXT:\n          promises.push(FreeTextAnnotation.createNewPrintAnnotation(annotationGlobals, xref, annotation, {\n            evaluator,\n            task,\n            evaluatorOptions: options\n          }));\n          break;\n        case AnnotationEditorType.HIGHLIGHT:\n          if (annotation.quadPoints) {\n            promises.push(HighlightAnnotation.createNewPrintAnnotation(annotationGlobals, xref, annotation, {\n              evaluatorOptions: options\n            }));\n          } else {\n            promises.push(InkAnnotation.createNewPrintAnnotation(annotationGlobals, xref, annotation, {\n              evaluatorOptions: options\n            }));\n          }\n          break;\n        case AnnotationEditorType.INK:\n          promises.push(InkAnnotation.createNewPrintAnnotation(annotationGlobals, xref, annotation, {\n            evaluatorOptions: options\n          }));\n          break;\n        case AnnotationEditorType.STAMP:\n          if (!options.isOffscreenCanvasSupported) {\n            break;\n          }\n          const image = await imagePromises.get(annotation.bitmapId);\n          if (image.imageStream) {\n            const {\n              imageStream,\n              smaskStream\n            } = image;\n            if (smaskStream) {\n              imageStream.dict.set(\"SMask\", smaskStream);\n            }\n            image.imageRef = new JpegStream(imageStream, imageStream.length);\n            image.imageStream = image.smaskStream = null;\n          }\n          promises.push(StampAnnotation.createNewPrintAnnotation(annotationGlobals, xref, annotation, {\n            image,\n            evaluatorOptions: options\n          }));\n          break;\n      }\n    }\n    return Promise.all(promises);\n  }\n}\nfunction getRgbColor(color, defaultColor = new Uint8ClampedArray(3)) {\n  if (!Array.isArray(color)) {\n    return defaultColor;\n  }\n  const rgbColor = defaultColor || new Uint8ClampedArray(3);\n  switch (color.length) {\n    case 0:\n      return null;\n    case 1:\n      ColorSpace.singletons.gray.getRgbItem(color, 0, rgbColor, 0);\n      return rgbColor;\n    case 3:\n      ColorSpace.singletons.rgb.getRgbItem(color, 0, rgbColor, 0);\n      return rgbColor;\n    case 4:\n      ColorSpace.singletons.cmyk.getRgbItem(color, 0, rgbColor, 0);\n      return rgbColor;\n    default:\n      return defaultColor;\n  }\n}\nfunction getPdfColorArray(color) {\n  return Array.from(color, c => c / 255);\n}\nfunction getQuadPoints(dict, rect) {\n  const quadPoints = dict.getArray(\"QuadPoints\");\n  if (!Array.isArray(quadPoints) || quadPoints.length === 0 || quadPoints.length % 8 > 0) {\n    return null;\n  }\n  const quadPointsLists = [];\n  for (let i = 0, ii = quadPoints.length / 8; i < ii; i++) {\n    let minX = Infinity,\n      maxX = -Infinity,\n      minY = Infinity,\n      maxY = -Infinity;\n    for (let j = i * 8, jj = i * 8 + 8; j < jj; j += 2) {\n      const x = quadPoints[j];\n      const y = quadPoints[j + 1];\n      minX = Math.min(x, minX);\n      maxX = Math.max(x, maxX);\n      minY = Math.min(y, minY);\n      maxY = Math.max(y, maxY);\n    }\n    if (rect !== null && (minX < rect[0] || maxX > rect[2] || minY < rect[1] || maxY > rect[3])) {\n      return null;\n    }\n    quadPointsLists.push([{\n      x: minX,\n      y: maxY\n    }, {\n      x: maxX,\n      y: maxY\n    }, {\n      x: minX,\n      y: minY\n    }, {\n      x: maxX,\n      y: minY\n    }]);\n  }\n  return quadPointsLists;\n}\nfunction getTransformMatrix(rect, bbox, matrix) {\n  const [minX, minY, maxX, maxY] = Util.getAxialAlignedBoundingBox(bbox, matrix);\n  if (minX === maxX || minY === maxY) {\n    return [1, 0, 0, 1, rect[0], rect[1]];\n  }\n  const xRatio = (rect[2] - rect[0]) / (maxX - minX);\n  const yRatio = (rect[3] - rect[1]) / (maxY - minY);\n  return [xRatio, 0, 0, yRatio, rect[0] - minX * xRatio, rect[1] - minY * yRatio];\n}\nclass Annotation {\n  constructor(params) {\n    const {\n      dict,\n      xref,\n      annotationGlobals\n    } = params;\n    this.setTitle(dict.get(\"T\"));\n    this.setContents(dict.get(\"Contents\"));\n    this.setModificationDate(dict.get(\"M\"));\n    this.setFlags(dict.get(\"F\"));\n    this.setRectangle(dict.getArray(\"Rect\"));\n    this.setColor(dict.getArray(\"C\"));\n    this.setBorderStyle(dict);\n    this.setAppearance(dict);\n    this.setOptionalContent(dict);\n    const MK = dict.get(\"MK\");\n    this.setBorderAndBackgroundColors(MK);\n    this.setRotation(MK, dict);\n    this.ref = params.ref instanceof Ref ? params.ref : null;\n    this._streams = [];\n    if (this.appearance) {\n      this._streams.push(this.appearance);\n    }\n    const isLocked = !!(this.flags & AnnotationFlag.LOCKED);\n    const isContentLocked = !!(this.flags & AnnotationFlag.LOCKEDCONTENTS);\n    if (annotationGlobals.structTreeRoot) {\n      let structParent = dict.get(\"StructParent\");\n      structParent = Number.isInteger(structParent) && structParent >= 0 ? structParent : -1;\n      annotationGlobals.structTreeRoot.addAnnotationIdToPage(params.pageRef, structParent);\n    }\n    this.data = {\n      annotationFlags: this.flags,\n      borderStyle: this.borderStyle,\n      color: this.color,\n      backgroundColor: this.backgroundColor,\n      borderColor: this.borderColor,\n      rotation: this.rotation,\n      contentsObj: this._contents,\n      hasAppearance: !!this.appearance,\n      id: params.id,\n      modificationDate: this.modificationDate,\n      rect: this.rectangle,\n      subtype: params.subtype,\n      hasOwnCanvas: false,\n      noRotate: !!(this.flags & AnnotationFlag.NOROTATE),\n      noHTML: isLocked && isContentLocked\n    };\n    if (params.collectFields) {\n      const kids = dict.get(\"Kids\");\n      if (Array.isArray(kids)) {\n        const kidIds = [];\n        for (const kid of kids) {\n          if (kid instanceof Ref) {\n            kidIds.push(kid.toString());\n          }\n        }\n        if (kidIds.length !== 0) {\n          this.data.kidIds = kidIds;\n        }\n      }\n      this.data.actions = collectActions(xref, dict, AnnotationActionEventType);\n      this.data.fieldName = this._constructFieldName(dict);\n      this.data.pageIndex = params.pageIndex;\n    }\n    this._isOffscreenCanvasSupported = params.evaluatorOptions.isOffscreenCanvasSupported;\n    this._fallbackFontDict = null;\n    this._needAppearances = false;\n  }\n  _hasFlag(flags, flag) {\n    return !!(flags & flag);\n  }\n  _isViewable(flags) {\n    return !this._hasFlag(flags, AnnotationFlag.INVISIBLE) && !this._hasFlag(flags, AnnotationFlag.NOVIEW);\n  }\n  _isPrintable(flags) {\n    return this._hasFlag(flags, AnnotationFlag.PRINT) && !this._hasFlag(flags, AnnotationFlag.HIDDEN) && !this._hasFlag(flags, AnnotationFlag.INVISIBLE);\n  }\n  mustBeViewed(annotationStorage, _renderForms) {\n    const noView = annotationStorage?.get(this.data.id)?.noView;\n    if (noView !== undefined) {\n      return !noView;\n    }\n    return this.viewable && !this._hasFlag(this.flags, AnnotationFlag.HIDDEN);\n  }\n  mustBePrinted(annotationStorage) {\n    const noPrint = annotationStorage?.get(this.data.id)?.noPrint;\n    if (noPrint !== undefined) {\n      return !noPrint;\n    }\n    return this.printable;\n  }\n  get viewable() {\n    if (this.data.quadPoints === null) {\n      return false;\n    }\n    if (this.flags === 0) {\n      return true;\n    }\n    return this._isViewable(this.flags);\n  }\n  get printable() {\n    if (this.data.quadPoints === null) {\n      return false;\n    }\n    if (this.flags === 0) {\n      return false;\n    }\n    return this._isPrintable(this.flags);\n  }\n  _parseStringHelper(data) {\n    const str = typeof data === \"string\" ? stringToPDFString(data) : \"\";\n    const dir = str && bidi(str).dir === \"rtl\" ? \"rtl\" : \"ltr\";\n    return {\n      str,\n      dir\n    };\n  }\n  setDefaultAppearance(params) {\n    const {\n      dict,\n      annotationGlobals\n    } = params;\n    const defaultAppearance = getInheritableProperty({\n      dict,\n      key: \"DA\"\n    }) || annotationGlobals.acroForm.get(\"DA\");\n    this._defaultAppearance = typeof defaultAppearance === \"string\" ? defaultAppearance : \"\";\n    this.data.defaultAppearanceData = parseDefaultAppearance(this._defaultAppearance);\n  }\n  setTitle(title) {\n    this._title = this._parseStringHelper(title);\n  }\n  setContents(contents) {\n    this._contents = this._parseStringHelper(contents);\n  }\n  setModificationDate(modificationDate) {\n    this.modificationDate = typeof modificationDate === \"string\" ? modificationDate : null;\n  }\n  setFlags(flags) {\n    this.flags = Number.isInteger(flags) && flags > 0 ? flags : 0;\n    if (this.flags & AnnotationFlag.INVISIBLE && this.constructor.name !== \"Annotation\") {\n      this.flags ^= AnnotationFlag.INVISIBLE;\n    }\n  }\n  hasFlag(flag) {\n    return this._hasFlag(this.flags, flag);\n  }\n  setRectangle(rectangle) {\n    this.rectangle = Array.isArray(rectangle) && rectangle.length === 4 ? Util.normalizeRect(rectangle) : [0, 0, 0, 0];\n  }\n  setColor(color) {\n    this.color = getRgbColor(color);\n  }\n  setLineEndings(lineEndings) {\n    this.lineEndings = [\"None\", \"None\"];\n    if (Array.isArray(lineEndings) && lineEndings.length === 2) {\n      for (let i = 0; i < 2; i++) {\n        const obj = lineEndings[i];\n        if (obj instanceof Name) {\n          switch (obj.name) {\n            case \"None\":\n              continue;\n            case \"Square\":\n            case \"Circle\":\n            case \"Diamond\":\n            case \"OpenArrow\":\n            case \"ClosedArrow\":\n            case \"Butt\":\n            case \"ROpenArrow\":\n            case \"RClosedArrow\":\n            case \"Slash\":\n              this.lineEndings[i] = obj.name;\n              continue;\n          }\n        }\n        warn(`Ignoring invalid lineEnding: ${obj}`);\n      }\n    }\n  }\n  setRotation(mk, dict) {\n    this.rotation = 0;\n    let angle = mk instanceof Dict ? mk.get(\"R\") || 0 : dict.get(\"Rotate\") || 0;\n    if (Number.isInteger(angle) && angle !== 0) {\n      angle %= 360;\n      if (angle < 0) {\n        angle += 360;\n      }\n      if (angle % 90 === 0) {\n        this.rotation = angle;\n      }\n    }\n  }\n  setBorderAndBackgroundColors(mk) {\n    if (mk instanceof Dict) {\n      this.borderColor = getRgbColor(mk.getArray(\"BC\"), null);\n      this.backgroundColor = getRgbColor(mk.getArray(\"BG\"), null);\n    } else {\n      this.borderColor = this.backgroundColor = null;\n    }\n  }\n  setBorderStyle(borderStyle) {\n    this.borderStyle = new AnnotationBorderStyle();\n    if (!(borderStyle instanceof Dict)) {\n      return;\n    }\n    if (borderStyle.has(\"BS\")) {\n      const dict = borderStyle.get(\"BS\");\n      if (dict instanceof Dict) {\n        const dictType = dict.get(\"Type\");\n        if (!dictType || isName(dictType, \"Border\")) {\n          this.borderStyle.setWidth(dict.get(\"W\"), this.rectangle);\n          this.borderStyle.setStyle(dict.get(\"S\"));\n          this.borderStyle.setDashArray(dict.getArray(\"D\"));\n        }\n      }\n    } else if (borderStyle.has(\"Border\")) {\n      const array = borderStyle.getArray(\"Border\");\n      if (Array.isArray(array) && array.length >= 3) {\n        this.borderStyle.setHorizontalCornerRadius(array[0]);\n        this.borderStyle.setVerticalCornerRadius(array[1]);\n        this.borderStyle.setWidth(array[2], this.rectangle);\n        if (array.length === 4) {\n          this.borderStyle.setDashArray(array[3], true);\n        }\n      }\n    } else {\n      this.borderStyle.setWidth(0);\n    }\n  }\n  setAppearance(dict) {\n    this.appearance = null;\n    const appearanceStates = dict.get(\"AP\");\n    if (!(appearanceStates instanceof Dict)) {\n      return;\n    }\n    const normalAppearanceState = appearanceStates.get(\"N\");\n    if (normalAppearanceState instanceof BaseStream) {\n      this.appearance = normalAppearanceState;\n      return;\n    }\n    if (!(normalAppearanceState instanceof Dict)) {\n      return;\n    }\n    const as = dict.get(\"AS\");\n    if (!(as instanceof Name) || !normalAppearanceState.has(as.name)) {\n      return;\n    }\n    const appearance = normalAppearanceState.get(as.name);\n    if (appearance instanceof BaseStream) {\n      this.appearance = appearance;\n    }\n  }\n  setOptionalContent(dict) {\n    this.oc = null;\n    const oc = dict.get(\"OC\");\n    if (oc instanceof Name) {\n      warn(\"setOptionalContent: Support for /Name-entry is not implemented.\");\n    } else if (oc instanceof Dict) {\n      this.oc = oc;\n    }\n  }\n  loadResources(keys, appearance) {\n    return appearance.dict.getAsync(\"Resources\").then(resources => {\n      if (!resources) {\n        return undefined;\n      }\n      const objectLoader = new ObjectLoader(resources, keys, resources.xref);\n      return objectLoader.load().then(function () {\n        return resources;\n      });\n    });\n  }\n  async getOperatorList(evaluator, task, intent, renderForms, annotationStorage) {\n    const data = this.data;\n    let appearance = this.appearance;\n    const isUsingOwnCanvas = !!(this.data.hasOwnCanvas && intent & RenderingIntentFlag.DISPLAY);\n    if (!appearance) {\n      if (!isUsingOwnCanvas) {\n        return {\n          opList: new OperatorList(),\n          separateForm: false,\n          separateCanvas: false\n        };\n      }\n      appearance = new StringStream(\"\");\n      appearance.dict = new Dict();\n    }\n    const appearanceDict = appearance.dict;\n    const resources = await this.loadResources([\"ExtGState\", \"ColorSpace\", \"Pattern\", \"Shading\", \"XObject\", \"Font\"], appearance);\n    const bbox = appearanceDict.getArray(\"BBox\") || [0, 0, 1, 1];\n    const matrix = appearanceDict.getArray(\"Matrix\") || [1, 0, 0, 1, 0, 0];\n    const transform = getTransformMatrix(data.rect, bbox, matrix);\n    const opList = new OperatorList();\n    let optionalContent;\n    if (this.oc) {\n      optionalContent = await evaluator.parseMarkedContentProps(this.oc, null);\n    }\n    if (optionalContent !== undefined) {\n      opList.addOp(OPS.beginMarkedContentProps, [\"OC\", optionalContent]);\n    }\n    opList.addOp(OPS.beginAnnotation, [data.id, data.rect, transform, matrix, isUsingOwnCanvas]);\n    await evaluator.getOperatorList({\n      stream: appearance,\n      task,\n      resources,\n      operatorList: opList,\n      fallbackFontDict: this._fallbackFontDict\n    });\n    opList.addOp(OPS.endAnnotation, []);\n    if (optionalContent !== undefined) {\n      opList.addOp(OPS.endMarkedContent, []);\n    }\n    this.reset();\n    return {\n      opList,\n      separateForm: false,\n      separateCanvas: isUsingOwnCanvas\n    };\n  }\n  async save(evaluator, task, annotationStorage) {\n    return null;\n  }\n  get hasTextContent() {\n    return false;\n  }\n  async extractTextContent(evaluator, task, viewBox) {\n    if (!this.appearance) {\n      return;\n    }\n    const resources = await this.loadResources([\"ExtGState\", \"Font\", \"Properties\", \"XObject\"], this.appearance);\n    const text = [];\n    const buffer = [];\n    let firstPosition = null;\n    const sink = {\n      desiredSize: Math.Infinity,\n      ready: true,\n      enqueue(chunk, size) {\n        for (const item of chunk.items) {\n          if (item.str === undefined) {\n            continue;\n          }\n          firstPosition ||= item.transform.slice(-2);\n          buffer.push(item.str);\n          if (item.hasEOL) {\n            text.push(buffer.join(\"\").trimEnd());\n            buffer.length = 0;\n          }\n        }\n      }\n    };\n    await evaluator.getTextContent({\n      stream: this.appearance,\n      task,\n      resources,\n      includeMarkedContent: true,\n      keepWhiteSpace: true,\n      sink,\n      viewBox\n    });\n    this.reset();\n    if (buffer.length) {\n      text.push(buffer.join(\"\").trimEnd());\n    }\n    if (text.length > 1 || text[0]) {\n      const appearanceDict = this.appearance.dict;\n      this.data.textPosition = this._transformPoint(firstPosition, appearanceDict.getArray(\"BBox\"), appearanceDict.getArray(\"Matrix\"));\n      this.data.textContent = text;\n    }\n  }\n  _transformPoint(coords, bbox, matrix) {\n    const {\n      rect\n    } = this.data;\n    bbox ||= [0, 0, 1, 1];\n    matrix ||= [1, 0, 0, 1, 0, 0];\n    const transform = getTransformMatrix(rect, bbox, matrix);\n    transform[4] -= rect[0];\n    transform[5] -= rect[1];\n    coords = Util.applyTransform(coords, transform);\n    return Util.applyTransform(coords, matrix);\n  }\n  getFieldObject() {\n    if (this.data.kidIds) {\n      return {\n        id: this.data.id,\n        actions: this.data.actions,\n        name: this.data.fieldName,\n        strokeColor: this.data.borderColor,\n        fillColor: this.data.backgroundColor,\n        type: \"\",\n        kidIds: this.data.kidIds,\n        page: this.data.pageIndex,\n        rotation: this.rotation\n      };\n    }\n    return null;\n  }\n  reset() {\n    for (const stream of this._streams) {\n      stream.reset();\n    }\n  }\n  _constructFieldName(dict) {\n    if (!dict.has(\"T\") && !dict.has(\"Parent\")) {\n      warn(\"Unknown field name, falling back to empty field name.\");\n      return \"\";\n    }\n    if (!dict.has(\"Parent\")) {\n      return stringToPDFString(dict.get(\"T\"));\n    }\n    const fieldName = [];\n    if (dict.has(\"T\")) {\n      fieldName.unshift(stringToPDFString(dict.get(\"T\")));\n    }\n    let loopDict = dict;\n    const visited = new RefSet();\n    if (dict.objId) {\n      visited.put(dict.objId);\n    }\n    while (loopDict.has(\"Parent\")) {\n      loopDict = loopDict.get(\"Parent\");\n      if (!(loopDict instanceof Dict) || loopDict.objId && visited.has(loopDict.objId)) {\n        break;\n      }\n      if (loopDict.objId) {\n        visited.put(loopDict.objId);\n      }\n      if (loopDict.has(\"T\")) {\n        fieldName.unshift(stringToPDFString(loopDict.get(\"T\")));\n      }\n    }\n    return fieldName.join(\".\");\n  }\n}\nclass AnnotationBorderStyle {\n  constructor() {\n    this.width = 1;\n    this.style = AnnotationBorderStyleType.SOLID;\n    this.dashArray = [3];\n    this.horizontalCornerRadius = 0;\n    this.verticalCornerRadius = 0;\n  }\n  setWidth(width, rect = [0, 0, 0, 0]) {\n    if (width instanceof Name) {\n      this.width = 0;\n      return;\n    }\n    if (typeof width === \"number\") {\n      if (width > 0) {\n        const maxWidth = (rect[2] - rect[0]) / 2;\n        const maxHeight = (rect[3] - rect[1]) / 2;\n        if (maxWidth > 0 && maxHeight > 0 && (width > maxWidth || width > maxHeight)) {\n          warn(`AnnotationBorderStyle.setWidth - ignoring width: ${width}`);\n          width = 1;\n        }\n      }\n      this.width = width;\n    }\n  }\n  setStyle(style) {\n    if (!(style instanceof Name)) {\n      return;\n    }\n    switch (style.name) {\n      case \"S\":\n        this.style = AnnotationBorderStyleType.SOLID;\n        break;\n      case \"D\":\n        this.style = AnnotationBorderStyleType.DASHED;\n        break;\n      case \"B\":\n        this.style = AnnotationBorderStyleType.BEVELED;\n        break;\n      case \"I\":\n        this.style = AnnotationBorderStyleType.INSET;\n        break;\n      case \"U\":\n        this.style = AnnotationBorderStyleType.UNDERLINE;\n        break;\n      default:\n        break;\n    }\n  }\n  setDashArray(dashArray, forceStyle = false) {\n    if (Array.isArray(dashArray) && dashArray.length > 0) {\n      let isValid = true;\n      let allZeros = true;\n      for (const element of dashArray) {\n        const validNumber = +element >= 0;\n        if (!validNumber) {\n          isValid = false;\n          break;\n        } else if (element > 0) {\n          allZeros = false;\n        }\n      }\n      if (isValid && !allZeros) {\n        this.dashArray = dashArray;\n        if (forceStyle) {\n          this.setStyle(Name.get(\"D\"));\n        }\n      } else {\n        this.width = 0;\n      }\n    } else if (dashArray) {\n      this.width = 0;\n    }\n  }\n  setHorizontalCornerRadius(radius) {\n    if (Number.isInteger(radius)) {\n      this.horizontalCornerRadius = radius;\n    }\n  }\n  setVerticalCornerRadius(radius) {\n    if (Number.isInteger(radius)) {\n      this.verticalCornerRadius = radius;\n    }\n  }\n}\nclass MarkupAnnotation extends Annotation {\n  constructor(params) {\n    super(params);\n    const {\n      dict\n    } = params;\n    if (dict.has(\"IRT\")) {\n      const rawIRT = dict.getRaw(\"IRT\");\n      this.data.inReplyTo = rawIRT instanceof Ref ? rawIRT.toString() : null;\n      const rt = dict.get(\"RT\");\n      this.data.replyType = rt instanceof Name ? rt.name : AnnotationReplyType.REPLY;\n    }\n    let popupRef = null;\n    if (this.data.replyType === AnnotationReplyType.GROUP) {\n      const parent = dict.get(\"IRT\");\n      this.setTitle(parent.get(\"T\"));\n      this.data.titleObj = this._title;\n      this.setContents(parent.get(\"Contents\"));\n      this.data.contentsObj = this._contents;\n      if (!parent.has(\"CreationDate\")) {\n        this.data.creationDate = null;\n      } else {\n        this.setCreationDate(parent.get(\"CreationDate\"));\n        this.data.creationDate = this.creationDate;\n      }\n      if (!parent.has(\"M\")) {\n        this.data.modificationDate = null;\n      } else {\n        this.setModificationDate(parent.get(\"M\"));\n        this.data.modificationDate = this.modificationDate;\n      }\n      popupRef = parent.getRaw(\"Popup\");\n      if (!parent.has(\"C\")) {\n        this.data.color = null;\n      } else {\n        this.setColor(parent.getArray(\"C\"));\n        this.data.color = this.color;\n      }\n    } else {\n      this.data.titleObj = this._title;\n      this.setCreationDate(dict.get(\"CreationDate\"));\n      this.data.creationDate = this.creationDate;\n      popupRef = dict.getRaw(\"Popup\");\n      if (!dict.has(\"C\")) {\n        this.data.color = null;\n      }\n    }\n    this.data.popupRef = popupRef instanceof Ref ? popupRef.toString() : null;\n    if (dict.has(\"RC\")) {\n      this.data.richText = XFAFactory.getRichTextAsHtml(dict.get(\"RC\"));\n    }\n  }\n  setCreationDate(creationDate) {\n    this.creationDate = typeof creationDate === \"string\" ? creationDate : null;\n  }\n  _setDefaultAppearance({\n    xref,\n    extra,\n    strokeColor,\n    fillColor,\n    blendMode,\n    strokeAlpha,\n    fillAlpha,\n    pointsCallback\n  }) {\n    let minX = Number.MAX_VALUE;\n    let minY = Number.MAX_VALUE;\n    let maxX = Number.MIN_VALUE;\n    let maxY = Number.MIN_VALUE;\n    const buffer = [\"q\"];\n    if (extra) {\n      buffer.push(extra);\n    }\n    if (strokeColor) {\n      buffer.push(`${strokeColor[0]} ${strokeColor[1]} ${strokeColor[2]} RG`);\n    }\n    if (fillColor) {\n      buffer.push(`${fillColor[0]} ${fillColor[1]} ${fillColor[2]} rg`);\n    }\n    let pointsArray = this.data.quadPoints;\n    if (!pointsArray) {\n      pointsArray = [[{\n        x: this.rectangle[0],\n        y: this.rectangle[3]\n      }, {\n        x: this.rectangle[2],\n        y: this.rectangle[3]\n      }, {\n        x: this.rectangle[0],\n        y: this.rectangle[1]\n      }, {\n        x: this.rectangle[2],\n        y: this.rectangle[1]\n      }]];\n    }\n    for (const points of pointsArray) {\n      const [mX, MX, mY, MY] = pointsCallback(buffer, points);\n      minX = Math.min(minX, mX);\n      maxX = Math.max(maxX, MX);\n      minY = Math.min(minY, mY);\n      maxY = Math.max(maxY, MY);\n    }\n    buffer.push(\"Q\");\n    const formDict = new Dict(xref);\n    const appearanceStreamDict = new Dict(xref);\n    appearanceStreamDict.set(\"Subtype\", Name.get(\"Form\"));\n    const appearanceStream = new StringStream(buffer.join(\" \"));\n    appearanceStream.dict = appearanceStreamDict;\n    formDict.set(\"Fm0\", appearanceStream);\n    const gsDict = new Dict(xref);\n    if (blendMode) {\n      gsDict.set(\"BM\", Name.get(blendMode));\n    }\n    if (typeof strokeAlpha === \"number\") {\n      gsDict.set(\"CA\", strokeAlpha);\n    }\n    if (typeof fillAlpha === \"number\") {\n      gsDict.set(\"ca\", fillAlpha);\n    }\n    const stateDict = new Dict(xref);\n    stateDict.set(\"GS0\", gsDict);\n    const resources = new Dict(xref);\n    resources.set(\"ExtGState\", stateDict);\n    resources.set(\"XObject\", formDict);\n    const appearanceDict = new Dict(xref);\n    appearanceDict.set(\"Resources\", resources);\n    const bbox = this.data.rect = [minX, minY, maxX, maxY];\n    appearanceDict.set(\"BBox\", bbox);\n    this.appearance = new StringStream(\"/GS0 gs /Fm0 Do\");\n    this.appearance.dict = appearanceDict;\n    this._streams.push(this.appearance, appearanceStream);\n  }\n  static async createNewAnnotation(xref, annotation, dependencies, params) {\n    const annotationRef = annotation.ref ||= xref.getNewTemporaryRef();\n    const ap = await this.createNewAppearanceStream(annotation, xref, params);\n    const buffer = [];\n    let annotationDict;\n    if (ap) {\n      const apRef = xref.getNewTemporaryRef();\n      annotationDict = this.createNewDict(annotation, xref, {\n        apRef\n      });\n      await writeObject(apRef, ap, buffer, xref);\n      dependencies.push({\n        ref: apRef,\n        data: buffer.join(\"\")\n      });\n    } else {\n      annotationDict = this.createNewDict(annotation, xref, {});\n    }\n    if (Number.isInteger(annotation.parentTreeId)) {\n      annotationDict.set(\"StructParent\", annotation.parentTreeId);\n    }\n    buffer.length = 0;\n    await writeObject(annotationRef, annotationDict, buffer, xref);\n    return {\n      ref: annotationRef,\n      data: buffer.join(\"\")\n    };\n  }\n  static async createNewPrintAnnotation(annotationGlobals, xref, annotation, params) {\n    const ap = await this.createNewAppearanceStream(annotation, xref, params);\n    const annotationDict = this.createNewDict(annotation, xref, {\n      ap\n    });\n    const newAnnotation = new this.prototype.constructor({\n      dict: annotationDict,\n      xref,\n      annotationGlobals,\n      evaluatorOptions: params.evaluatorOptions\n    });\n    if (annotation.ref) {\n      newAnnotation.ref = newAnnotation.refToReplace = annotation.ref;\n    }\n    return newAnnotation;\n  }\n}\nclass WidgetAnnotation extends Annotation {\n  constructor(params) {\n    super(params);\n    const {\n      dict,\n      xref,\n      annotationGlobals\n    } = params;\n    const data = this.data;\n    this._needAppearances = params.needAppearances;\n    data.annotationType = AnnotationType.WIDGET;\n    if (data.fieldName === undefined) {\n      data.fieldName = this._constructFieldName(dict);\n    }\n    if (data.actions === undefined) {\n      data.actions = collectActions(xref, dict, AnnotationActionEventType);\n    }\n    let fieldValue = getInheritableProperty({\n      dict,\n      key: \"V\",\n      getArray: true\n    });\n    data.fieldValue = this._decodeFormValue(fieldValue);\n    const defaultFieldValue = getInheritableProperty({\n      dict,\n      key: \"DV\",\n      getArray: true\n    });\n    data.defaultFieldValue = this._decodeFormValue(defaultFieldValue);\n    if (fieldValue === undefined && annotationGlobals.xfaDatasets) {\n      const path = this._title.str;\n      if (path) {\n        this._hasValueFromXFA = true;\n        data.fieldValue = fieldValue = annotationGlobals.xfaDatasets.getValue(path);\n      }\n    }\n    if (fieldValue === undefined && data.defaultFieldValue !== null) {\n      data.fieldValue = data.defaultFieldValue;\n    }\n    data.alternativeText = stringToPDFString(dict.get(\"TU\") || \"\");\n    this.setDefaultAppearance(params);\n    data.hasAppearance ||= this._needAppearances && data.fieldValue !== undefined && data.fieldValue !== null;\n    const fieldType = getInheritableProperty({\n      dict,\n      key: \"FT\"\n    });\n    data.fieldType = fieldType instanceof Name ? fieldType.name : null;\n    const localResources = getInheritableProperty({\n      dict,\n      key: \"DR\"\n    });\n    const acroFormResources = annotationGlobals.acroForm.get(\"DR\");\n    const appearanceResources = this.appearance?.dict.get(\"Resources\");\n    this._fieldResources = {\n      localResources,\n      acroFormResources,\n      appearanceResources,\n      mergedResources: Dict.merge({\n        xref,\n        dictArray: [localResources, appearanceResources, acroFormResources],\n        mergeSubDicts: true\n      })\n    };\n    data.fieldFlags = getInheritableProperty({\n      dict,\n      key: \"Ff\"\n    });\n    if (!Number.isInteger(data.fieldFlags) || data.fieldFlags < 0) {\n      data.fieldFlags = 0;\n    }\n    data.readOnly = this.hasFieldFlag(AnnotationFieldFlag.READONLY);\n    data.required = this.hasFieldFlag(AnnotationFieldFlag.REQUIRED);\n    data.hidden = this._hasFlag(data.annotationFlags, AnnotationFlag.HIDDEN) || this._hasFlag(data.annotationFlags, AnnotationFlag.NOVIEW);\n  }\n  _decodeFormValue(formValue) {\n    if (Array.isArray(formValue)) {\n      return formValue.filter(item => typeof item === \"string\").map(item => stringToPDFString(item));\n    } else if (formValue instanceof Name) {\n      return stringToPDFString(formValue.name);\n    } else if (typeof formValue === \"string\") {\n      return stringToPDFString(formValue);\n    }\n    return null;\n  }\n  hasFieldFlag(flag) {\n    return !!(this.data.fieldFlags & flag);\n  }\n  _isViewable(flags) {\n    return true;\n  }\n  mustBeViewed(annotationStorage, renderForms) {\n    if (renderForms) {\n      return this.viewable;\n    }\n    return super.mustBeViewed(annotationStorage, renderForms) && !this._hasFlag(this.flags, AnnotationFlag.NOVIEW);\n  }\n  getRotationMatrix(annotationStorage) {\n    let rotation = annotationStorage?.get(this.data.id)?.rotation;\n    if (rotation === undefined) {\n      rotation = this.rotation;\n    }\n    if (rotation === 0) {\n      return IDENTITY_MATRIX;\n    }\n    const width = this.data.rect[2] - this.data.rect[0];\n    const height = this.data.rect[3] - this.data.rect[1];\n    return getRotationMatrix(rotation, width, height);\n  }\n  getBorderAndBackgroundAppearances(annotationStorage) {\n    let rotation = annotationStorage?.get(this.data.id)?.rotation;\n    if (rotation === undefined) {\n      rotation = this.rotation;\n    }\n    if (!this.backgroundColor && !this.borderColor) {\n      return \"\";\n    }\n    const width = this.data.rect[2] - this.data.rect[0];\n    const height = this.data.rect[3] - this.data.rect[1];\n    const rect = rotation === 0 || rotation === 180 ? `0 0 ${width} ${height} re` : `0 0 ${height} ${width} re`;\n    let str = \"\";\n    if (this.backgroundColor) {\n      str = `${getPdfColor(this.backgroundColor, true)} ${rect} f `;\n    }\n    if (this.borderColor) {\n      const borderWidth = this.borderStyle.width || 1;\n      str += `${borderWidth} w ${getPdfColor(this.borderColor, false)} ${rect} S `;\n    }\n    return str;\n  }\n  async getOperatorList(evaluator, task, intent, renderForms, annotationStorage) {\n    if (renderForms && !(this instanceof SignatureWidgetAnnotation) && !this.data.noHTML && !this.data.hasOwnCanvas) {\n      return {\n        opList: new OperatorList(),\n        separateForm: true,\n        separateCanvas: false\n      };\n    }\n    if (!this._hasText) {\n      return super.getOperatorList(evaluator, task, intent, renderForms, annotationStorage);\n    }\n    const content = await this._getAppearance(evaluator, task, intent, annotationStorage);\n    if (this.appearance && content === null) {\n      return super.getOperatorList(evaluator, task, intent, renderForms, annotationStorage);\n    }\n    const opList = new OperatorList();\n    if (!this._defaultAppearance || content === null) {\n      return {\n        opList,\n        separateForm: false,\n        separateCanvas: false\n      };\n    }\n    const isUsingOwnCanvas = !!(this.data.hasOwnCanvas && intent & RenderingIntentFlag.DISPLAY);\n    const matrix = [1, 0, 0, 1, 0, 0];\n    const bbox = [0, 0, this.data.rect[2] - this.data.rect[0], this.data.rect[3] - this.data.rect[1]];\n    const transform = getTransformMatrix(this.data.rect, bbox, matrix);\n    let optionalContent;\n    if (this.oc) {\n      optionalContent = await evaluator.parseMarkedContentProps(this.oc, null);\n    }\n    if (optionalContent !== undefined) {\n      opList.addOp(OPS.beginMarkedContentProps, [\"OC\", optionalContent]);\n    }\n    opList.addOp(OPS.beginAnnotation, [this.data.id, this.data.rect, transform, this.getRotationMatrix(annotationStorage), isUsingOwnCanvas]);\n    const stream = new StringStream(content);\n    await evaluator.getOperatorList({\n      stream,\n      task,\n      resources: this._fieldResources.mergedResources,\n      operatorList: opList\n    });\n    opList.addOp(OPS.endAnnotation, []);\n    if (optionalContent !== undefined) {\n      opList.addOp(OPS.endMarkedContent, []);\n    }\n    return {\n      opList,\n      separateForm: false,\n      separateCanvas: isUsingOwnCanvas\n    };\n  }\n  _getMKDict(rotation) {\n    const mk = new Dict(null);\n    if (rotation) {\n      mk.set(\"R\", rotation);\n    }\n    if (this.borderColor) {\n      mk.set(\"BC\", getPdfColorArray(this.borderColor));\n    }\n    if (this.backgroundColor) {\n      mk.set(\"BG\", getPdfColorArray(this.backgroundColor));\n    }\n    return mk.size > 0 ? mk : null;\n  }\n  amendSavedDict(annotationStorage, dict) {}\n  async save(evaluator, task, annotationStorage) {\n    const storageEntry = annotationStorage?.get(this.data.id);\n    let value = storageEntry?.value,\n      rotation = storageEntry?.rotation;\n    if (value === this.data.fieldValue || value === undefined) {\n      if (!this._hasValueFromXFA && rotation === undefined) {\n        return null;\n      }\n      value ||= this.data.fieldValue;\n    }\n    if (rotation === undefined && !this._hasValueFromXFA && Array.isArray(value) && Array.isArray(this.data.fieldValue) && value.length === this.data.fieldValue.length && value.every((x, i) => x === this.data.fieldValue[i])) {\n      return null;\n    }\n    if (rotation === undefined) {\n      rotation = this.rotation;\n    }\n    let appearance = null;\n    if (!this._needAppearances) {\n      appearance = await this._getAppearance(evaluator, task, RenderingIntentFlag.SAVE, annotationStorage);\n      if (appearance === null) {\n        return null;\n      }\n    } else {}\n    let needAppearances = false;\n    if (appearance?.needAppearances) {\n      needAppearances = true;\n      appearance = null;\n    }\n    const {\n      xref\n    } = evaluator;\n    const originalDict = xref.fetchIfRef(this.ref);\n    if (!(originalDict instanceof Dict)) {\n      return null;\n    }\n    const dict = new Dict(xref);\n    for (const key of originalDict.getKeys()) {\n      if (key !== \"AP\") {\n        dict.set(key, originalDict.getRaw(key));\n      }\n    }\n    const xfa = {\n      path: this.data.fieldName,\n      value\n    };\n    const encoder = val => isAscii(val) ? val : stringToUTF16String(val, true);\n    dict.set(\"V\", Array.isArray(value) ? value.map(encoder) : encoder(value));\n    this.amendSavedDict(annotationStorage, dict);\n    const maybeMK = this._getMKDict(rotation);\n    if (maybeMK) {\n      dict.set(\"MK\", maybeMK);\n    }\n    const buffer = [];\n    const changes = [{\n      ref: this.ref,\n      data: \"\",\n      xfa,\n      needAppearances\n    }];\n    if (appearance !== null) {\n      const newRef = xref.getNewTemporaryRef();\n      const AP = new Dict(xref);\n      dict.set(\"AP\", AP);\n      AP.set(\"N\", newRef);\n      const resources = this._getSaveFieldResources(xref);\n      const appearanceStream = new StringStream(appearance);\n      const appearanceDict = appearanceStream.dict = new Dict(xref);\n      appearanceDict.set(\"Subtype\", Name.get(\"Form\"));\n      appearanceDict.set(\"Resources\", resources);\n      appearanceDict.set(\"BBox\", [0, 0, this.data.rect[2] - this.data.rect[0], this.data.rect[3] - this.data.rect[1]]);\n      const rotationMatrix = this.getRotationMatrix(annotationStorage);\n      if (rotationMatrix !== IDENTITY_MATRIX) {\n        appearanceDict.set(\"Matrix\", rotationMatrix);\n      }\n      await writeObject(newRef, appearanceStream, buffer, xref);\n      changes.push({\n        ref: newRef,\n        data: buffer.join(\"\"),\n        xfa: null,\n        needAppearances: false\n      });\n      buffer.length = 0;\n    }\n    dict.set(\"M\", `D:${getModificationDate()}`);\n    await writeObject(this.ref, dict, buffer, xref);\n    changes[0].data = buffer.join(\"\");\n    return changes;\n  }\n  async _getAppearance(evaluator, task, intent, annotationStorage) {\n    const isPassword = this.hasFieldFlag(AnnotationFieldFlag.PASSWORD);\n    if (isPassword) {\n      return null;\n    }\n    const storageEntry = annotationStorage?.get(this.data.id);\n    let value, rotation;\n    if (storageEntry) {\n      value = storageEntry.formattedValue || storageEntry.value;\n      rotation = storageEntry.rotation;\n    }\n    if (rotation === undefined && value === undefined && !this._needAppearances) {\n      if (!this._hasValueFromXFA || this.appearance) {\n        return null;\n      }\n    }\n    const colors = this.getBorderAndBackgroundAppearances(annotationStorage);\n    if (value === undefined) {\n      value = this.data.fieldValue;\n      if (!value) {\n        return `/Tx BMC q ${colors}Q EMC`;\n      }\n    }\n    if (Array.isArray(value) && value.length === 1) {\n      value = value[0];\n    }\n    assert(typeof value === \"string\", \"Expected `value` to be a string.\");\n    value = value.trim();\n    if (this.data.combo) {\n      const option = this.data.options.find(({\n        exportValue\n      }) => value === exportValue);\n      value = option?.displayValue || value;\n    }\n    if (value === \"\") {\n      return `/Tx BMC q ${colors}Q EMC`;\n    }\n    if (rotation === undefined) {\n      rotation = this.rotation;\n    }\n    let lineCount = -1;\n    let lines;\n    if (this.data.multiLine) {\n      lines = value.split(/\\r\\n?|\\n/).map(line => line.normalize(\"NFC\"));\n      lineCount = lines.length;\n    } else {\n      lines = [value.replace(/\\r\\n?|\\n/, \"\").normalize(\"NFC\")];\n    }\n    const defaultPadding = 1;\n    const defaultHPadding = 2;\n    let totalHeight = this.data.rect[3] - this.data.rect[1];\n    let totalWidth = this.data.rect[2] - this.data.rect[0];\n    if (rotation === 90 || rotation === 270) {\n      [totalWidth, totalHeight] = [totalHeight, totalWidth];\n    }\n    if (!this._defaultAppearance) {\n      this.data.defaultAppearanceData = parseDefaultAppearance(this._defaultAppearance = \"/Helvetica 0 Tf 0 g\");\n    }\n    let font = await WidgetAnnotation._getFontData(evaluator, task, this.data.defaultAppearanceData, this._fieldResources.mergedResources);\n    let defaultAppearance, fontSize, lineHeight;\n    const encodedLines = [];\n    let encodingError = false;\n    for (const line of lines) {\n      const encodedString = font.encodeString(line);\n      if (encodedString.length > 1) {\n        encodingError = true;\n      }\n      encodedLines.push(encodedString.join(\"\"));\n    }\n    if (encodingError && intent & RenderingIntentFlag.SAVE) {\n      return {\n        needAppearances: true\n      };\n    }\n    if (encodingError && this._isOffscreenCanvasSupported) {\n      const fontFamily = this.data.comb ? \"monospace\" : \"sans-serif\";\n      const fakeUnicodeFont = new FakeUnicodeFont(evaluator.xref, fontFamily);\n      const resources = fakeUnicodeFont.createFontResources(lines.join(\"\"));\n      const newFont = resources.getRaw(\"Font\");\n      if (this._fieldResources.mergedResources.has(\"Font\")) {\n        const oldFont = this._fieldResources.mergedResources.get(\"Font\");\n        for (const key of newFont.getKeys()) {\n          oldFont.set(key, newFont.getRaw(key));\n        }\n      } else {\n        this._fieldResources.mergedResources.set(\"Font\", newFont);\n      }\n      const fontName = fakeUnicodeFont.fontName.name;\n      font = await WidgetAnnotation._getFontData(evaluator, task, {\n        fontName,\n        fontSize: 0\n      }, resources);\n      for (let i = 0, ii = encodedLines.length; i < ii; i++) {\n        encodedLines[i] = stringToUTF16String(lines[i]);\n      }\n      const savedDefaultAppearance = Object.assign(Object.create(null), this.data.defaultAppearanceData);\n      this.data.defaultAppearanceData.fontSize = 0;\n      this.data.defaultAppearanceData.fontName = fontName;\n      [defaultAppearance, fontSize, lineHeight] = this._computeFontSize(totalHeight - 2 * defaultPadding, totalWidth - 2 * defaultHPadding, value, font, lineCount);\n      this.data.defaultAppearanceData = savedDefaultAppearance;\n    } else {\n      if (!this._isOffscreenCanvasSupported) {\n        warn(\"_getAppearance: OffscreenCanvas is not supported, annotation may not render correctly.\");\n      }\n      [defaultAppearance, fontSize, lineHeight] = this._computeFontSize(totalHeight - 2 * defaultPadding, totalWidth - 2 * defaultHPadding, value, font, lineCount);\n    }\n    let descent = font.descent;\n    if (isNaN(descent)) {\n      descent = BASELINE_FACTOR * lineHeight;\n    } else {\n      descent = Math.max(BASELINE_FACTOR * lineHeight, Math.abs(descent) * fontSize);\n    }\n    const defaultVPadding = Math.min(Math.floor((totalHeight - fontSize) / 2), defaultPadding);\n    const alignment = this.data.textAlignment;\n    if (this.data.multiLine) {\n      return this._getMultilineAppearance(defaultAppearance, encodedLines, font, fontSize, totalWidth, totalHeight, alignment, defaultHPadding, defaultVPadding, descent, lineHeight, annotationStorage);\n    }\n    if (this.data.comb) {\n      return this._getCombAppearance(defaultAppearance, font, encodedLines[0], fontSize, totalWidth, totalHeight, defaultHPadding, defaultVPadding, descent, lineHeight, annotationStorage);\n    }\n    const bottomPadding = defaultVPadding + descent;\n    if (alignment === 0 || alignment > 2) {\n      return `/Tx BMC q ${colors}BT ` + defaultAppearance + ` 1 0 0 1 ${numberToString(defaultHPadding)} ${numberToString(bottomPadding)} Tm (${escapeString(encodedLines[0])}) Tj` + \" ET Q EMC\";\n    }\n    const prevInfo = {\n      shift: 0\n    };\n    const renderedText = this._renderText(encodedLines[0], font, fontSize, totalWidth, alignment, prevInfo, defaultHPadding, bottomPadding);\n    return `/Tx BMC q ${colors}BT ` + defaultAppearance + ` 1 0 0 1 0 0 Tm ${renderedText}` + \" ET Q EMC\";\n  }\n  static async _getFontData(evaluator, task, appearanceData, resources) {\n    const operatorList = new OperatorList();\n    const initialState = {\n      font: null,\n      clone() {\n        return this;\n      }\n    };\n    const {\n      fontName,\n      fontSize\n    } = appearanceData;\n    await evaluator.handleSetFont(resources, [fontName && Name.get(fontName), fontSize], null, operatorList, task, initialState, null);\n    return initialState.font;\n  }\n  _getTextWidth(text, font) {\n    return font.charsToGlyphs(text).reduce((width, glyph) => width + glyph.width, 0) / 1000;\n  }\n  _computeFontSize(height, width, text, font, lineCount) {\n    let {\n      fontSize\n    } = this.data.defaultAppearanceData;\n    let lineHeight = (fontSize || 12) * LINE_FACTOR,\n      numberOfLines = Math.round(height / lineHeight);\n    if (!fontSize) {\n      const roundWithTwoDigits = x => Math.floor(x * 100) / 100;\n      if (lineCount === -1) {\n        const textWidth = this._getTextWidth(text, font);\n        fontSize = roundWithTwoDigits(Math.min(height / LINE_FACTOR, textWidth > width ? width / textWidth : Infinity));\n        numberOfLines = 1;\n      } else {\n        const lines = text.split(/\\r\\n?|\\n/);\n        const cachedLines = [];\n        for (const line of lines) {\n          const encoded = font.encodeString(line).join(\"\");\n          const glyphs = font.charsToGlyphs(encoded);\n          const positions = font.getCharPositions(encoded);\n          cachedLines.push({\n            line: encoded,\n            glyphs,\n            positions\n          });\n        }\n        const isTooBig = fsize => {\n          let totalHeight = 0;\n          for (const cache of cachedLines) {\n            const chunks = this._splitLine(null, font, fsize, width, cache);\n            totalHeight += chunks.length * fsize;\n            if (totalHeight > height) {\n              return true;\n            }\n          }\n          return false;\n        };\n        numberOfLines = Math.max(numberOfLines, lineCount);\n        while (true) {\n          lineHeight = height / numberOfLines;\n          fontSize = roundWithTwoDigits(lineHeight / LINE_FACTOR);\n          if (isTooBig(fontSize)) {\n            numberOfLines++;\n            continue;\n          }\n          break;\n        }\n      }\n      const {\n        fontName,\n        fontColor\n      } = this.data.defaultAppearanceData;\n      this._defaultAppearance = createDefaultAppearance({\n        fontSize,\n        fontName,\n        fontColor\n      });\n    }\n    return [this._defaultAppearance, fontSize, height / numberOfLines];\n  }\n  _renderText(text, font, fontSize, totalWidth, alignment, prevInfo, hPadding, vPadding) {\n    let shift;\n    if (alignment === 1) {\n      const width = this._getTextWidth(text, font) * fontSize;\n      shift = (totalWidth - width) / 2;\n    } else if (alignment === 2) {\n      const width = this._getTextWidth(text, font) * fontSize;\n      shift = totalWidth - width - hPadding;\n    } else {\n      shift = hPadding;\n    }\n    const shiftStr = numberToString(shift - prevInfo.shift);\n    prevInfo.shift = shift;\n    vPadding = numberToString(vPadding);\n    return `${shiftStr} ${vPadding} Td (${escapeString(text)}) Tj`;\n  }\n  _getSaveFieldResources(xref) {\n    const {\n      localResources,\n      appearanceResources,\n      acroFormResources\n    } = this._fieldResources;\n    const fontName = this.data.defaultAppearanceData?.fontName;\n    if (!fontName) {\n      return localResources || Dict.empty;\n    }\n    for (const resources of [localResources, appearanceResources]) {\n      if (resources instanceof Dict) {\n        const localFont = resources.get(\"Font\");\n        if (localFont instanceof Dict && localFont.has(fontName)) {\n          return resources;\n        }\n      }\n    }\n    if (acroFormResources instanceof Dict) {\n      const acroFormFont = acroFormResources.get(\"Font\");\n      if (acroFormFont instanceof Dict && acroFormFont.has(fontName)) {\n        const subFontDict = new Dict(xref);\n        subFontDict.set(fontName, acroFormFont.getRaw(fontName));\n        const subResourcesDict = new Dict(xref);\n        subResourcesDict.set(\"Font\", subFontDict);\n        return Dict.merge({\n          xref,\n          dictArray: [subResourcesDict, localResources],\n          mergeSubDicts: true\n        });\n      }\n    }\n    return localResources || Dict.empty;\n  }\n  getFieldObject() {\n    return null;\n  }\n}\nclass TextWidgetAnnotation extends WidgetAnnotation {\n  constructor(params) {\n    super(params);\n    this.data.hasOwnCanvas = this.data.readOnly && !this.data.noHTML;\n    this._hasText = true;\n    const dict = params.dict;\n    if (typeof this.data.fieldValue !== \"string\") {\n      this.data.fieldValue = \"\";\n    }\n    let alignment = getInheritableProperty({\n      dict,\n      key: \"Q\"\n    });\n    if (!Number.isInteger(alignment) || alignment < 0 || alignment > 2) {\n      alignment = null;\n    }\n    this.data.textAlignment = alignment;\n    let maximumLength = getInheritableProperty({\n      dict,\n      key: \"MaxLen\"\n    });\n    if (!Number.isInteger(maximumLength) || maximumLength < 0) {\n      maximumLength = 0;\n    }\n    this.data.maxLen = maximumLength;\n    this.data.multiLine = this.hasFieldFlag(AnnotationFieldFlag.MULTILINE);\n    this.data.comb = this.hasFieldFlag(AnnotationFieldFlag.COMB) && !this.hasFieldFlag(AnnotationFieldFlag.MULTILINE) && !this.hasFieldFlag(AnnotationFieldFlag.PASSWORD) && !this.hasFieldFlag(AnnotationFieldFlag.FILESELECT) && this.data.maxLen !== 0;\n    this.data.doNotScroll = this.hasFieldFlag(AnnotationFieldFlag.DONOTSCROLL);\n  }\n  get hasTextContent() {\n    return !!this.appearance && !this._needAppearances;\n  }\n  _getCombAppearance(defaultAppearance, font, text, fontSize, width, height, hPadding, vPadding, descent, lineHeight, annotationStorage) {\n    const combWidth = width / this.data.maxLen;\n    const colors = this.getBorderAndBackgroundAppearances(annotationStorage);\n    const buf = [];\n    const positions = font.getCharPositions(text);\n    for (const [start, end] of positions) {\n      buf.push(`(${escapeString(text.substring(start, end))}) Tj`);\n    }\n    const renderedComb = buf.join(` ${numberToString(combWidth)} 0 Td `);\n    return `/Tx BMC q ${colors}BT ` + defaultAppearance + ` 1 0 0 1 ${numberToString(hPadding)} ${numberToString(vPadding + descent)} Tm ${renderedComb}` + \" ET Q EMC\";\n  }\n  _getMultilineAppearance(defaultAppearance, lines, font, fontSize, width, height, alignment, hPadding, vPadding, descent, lineHeight, annotationStorage) {\n    const buf = [];\n    const totalWidth = width - 2 * hPadding;\n    const prevInfo = {\n      shift: 0\n    };\n    for (let i = 0, ii = lines.length; i < ii; i++) {\n      const line = lines[i];\n      const chunks = this._splitLine(line, font, fontSize, totalWidth);\n      for (let j = 0, jj = chunks.length; j < jj; j++) {\n        const chunk = chunks[j];\n        const vShift = i === 0 && j === 0 ? -vPadding - (lineHeight - descent) : -lineHeight;\n        buf.push(this._renderText(chunk, font, fontSize, width, alignment, prevInfo, hPadding, vShift));\n      }\n    }\n    const colors = this.getBorderAndBackgroundAppearances(annotationStorage);\n    const renderedText = buf.join(\"\\n\");\n    return `/Tx BMC q ${colors}BT ` + defaultAppearance + ` 1 0 0 1 0 ${numberToString(height)} Tm ${renderedText}` + \" ET Q EMC\";\n  }\n  _splitLine(line, font, fontSize, width, cache = {}) {\n    line = cache.line || line;\n    const glyphs = cache.glyphs || font.charsToGlyphs(line);\n    if (glyphs.length <= 1) {\n      return [line];\n    }\n    const positions = cache.positions || font.getCharPositions(line);\n    const scale = fontSize / 1000;\n    const chunks = [];\n    let lastSpacePosInStringStart = -1,\n      lastSpacePosInStringEnd = -1,\n      lastSpacePos = -1,\n      startChunk = 0,\n      currentWidth = 0;\n    for (let i = 0, ii = glyphs.length; i < ii; i++) {\n      const [start, end] = positions[i];\n      const glyph = glyphs[i];\n      const glyphWidth = glyph.width * scale;\n      if (glyph.unicode === \" \") {\n        if (currentWidth + glyphWidth > width) {\n          chunks.push(line.substring(startChunk, start));\n          startChunk = start;\n          currentWidth = glyphWidth;\n          lastSpacePosInStringStart = -1;\n          lastSpacePos = -1;\n        } else {\n          currentWidth += glyphWidth;\n          lastSpacePosInStringStart = start;\n          lastSpacePosInStringEnd = end;\n          lastSpacePos = i;\n        }\n      } else if (currentWidth + glyphWidth > width) {\n        if (lastSpacePosInStringStart !== -1) {\n          chunks.push(line.substring(startChunk, lastSpacePosInStringEnd));\n          startChunk = lastSpacePosInStringEnd;\n          i = lastSpacePos + 1;\n          lastSpacePosInStringStart = -1;\n          currentWidth = 0;\n        } else {\n          chunks.push(line.substring(startChunk, start));\n          startChunk = start;\n          currentWidth = glyphWidth;\n        }\n      } else {\n        currentWidth += glyphWidth;\n      }\n    }\n    if (startChunk < line.length) {\n      chunks.push(line.substring(startChunk, line.length));\n    }\n    return chunks;\n  }\n  getFieldObject() {\n    return {\n      id: this.data.id,\n      value: this.data.fieldValue,\n      defaultValue: this.data.defaultFieldValue || \"\",\n      multiline: this.data.multiLine,\n      password: this.hasFieldFlag(AnnotationFieldFlag.PASSWORD),\n      charLimit: this.data.maxLen,\n      comb: this.data.comb,\n      editable: !this.data.readOnly,\n      hidden: this.data.hidden,\n      name: this.data.fieldName,\n      rect: this.data.rect,\n      actions: this.data.actions,\n      page: this.data.pageIndex,\n      strokeColor: this.data.borderColor,\n      fillColor: this.data.backgroundColor,\n      rotation: this.rotation,\n      type: \"text\"\n    };\n  }\n}\nclass ButtonWidgetAnnotation extends WidgetAnnotation {\n  constructor(params) {\n    super(params);\n    this.checkedAppearance = null;\n    this.uncheckedAppearance = null;\n    this.data.checkBox = !this.hasFieldFlag(AnnotationFieldFlag.RADIO) && !this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON);\n    this.data.radioButton = this.hasFieldFlag(AnnotationFieldFlag.RADIO) && !this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON);\n    this.data.pushButton = this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON);\n    this.data.isTooltipOnly = false;\n    if (this.data.checkBox) {\n      this._processCheckBox(params);\n    } else if (this.data.radioButton) {\n      this._processRadioButton(params);\n    } else if (this.data.pushButton) {\n      this.data.hasOwnCanvas = true;\n      this.data.noHTML = false;\n      this._processPushButton(params);\n    } else {\n      warn(\"Invalid field flags for button widget annotation\");\n    }\n  }\n  async getOperatorList(evaluator, task, intent, renderForms, annotationStorage) {\n    if (this.data.pushButton) {\n      return super.getOperatorList(evaluator, task, intent, false, annotationStorage);\n    }\n    let value = null;\n    let rotation = null;\n    if (annotationStorage) {\n      const storageEntry = annotationStorage.get(this.data.id);\n      value = storageEntry ? storageEntry.value : null;\n      rotation = storageEntry ? storageEntry.rotation : null;\n    }\n    if (value === null && this.appearance) {\n      return super.getOperatorList(evaluator, task, intent, renderForms, annotationStorage);\n    }\n    if (value === null || value === undefined) {\n      value = this.data.checkBox ? this.data.fieldValue === this.data.exportValue : this.data.fieldValue === this.data.buttonValue;\n    }\n    const appearance = value ? this.checkedAppearance : this.uncheckedAppearance;\n    if (appearance) {\n      const savedAppearance = this.appearance;\n      const savedMatrix = appearance.dict.getArray(\"Matrix\") || IDENTITY_MATRIX;\n      if (rotation) {\n        appearance.dict.set(\"Matrix\", this.getRotationMatrix(annotationStorage));\n      }\n      this.appearance = appearance;\n      const operatorList = super.getOperatorList(evaluator, task, intent, renderForms, annotationStorage);\n      this.appearance = savedAppearance;\n      appearance.dict.set(\"Matrix\", savedMatrix);\n      return operatorList;\n    }\n    return {\n      opList: new OperatorList(),\n      separateForm: false,\n      separateCanvas: false\n    };\n  }\n  async save(evaluator, task, annotationStorage) {\n    if (this.data.checkBox) {\n      return this._saveCheckbox(evaluator, task, annotationStorage);\n    }\n    if (this.data.radioButton) {\n      return this._saveRadioButton(evaluator, task, annotationStorage);\n    }\n    return null;\n  }\n  async _saveCheckbox(evaluator, task, annotationStorage) {\n    if (!annotationStorage) {\n      return null;\n    }\n    const storageEntry = annotationStorage.get(this.data.id);\n    let rotation = storageEntry?.rotation,\n      value = storageEntry?.value;\n    if (rotation === undefined) {\n      if (value === undefined) {\n        return null;\n      }\n      const defaultValue = this.data.fieldValue === this.data.exportValue;\n      if (defaultValue === value) {\n        return null;\n      }\n    }\n    const dict = evaluator.xref.fetchIfRef(this.ref);\n    if (!(dict instanceof Dict)) {\n      return null;\n    }\n    if (rotation === undefined) {\n      rotation = this.rotation;\n    }\n    if (value === undefined) {\n      value = this.data.fieldValue === this.data.exportValue;\n    }\n    const xfa = {\n      path: this.data.fieldName,\n      value: value ? this.data.exportValue : \"\"\n    };\n    const name = Name.get(value ? this.data.exportValue : \"Off\");\n    dict.set(\"V\", name);\n    dict.set(\"AS\", name);\n    dict.set(\"M\", `D:${getModificationDate()}`);\n    const maybeMK = this._getMKDict(rotation);\n    if (maybeMK) {\n      dict.set(\"MK\", maybeMK);\n    }\n    const buffer = [];\n    await writeObject(this.ref, dict, buffer, evaluator.xref);\n    return [{\n      ref: this.ref,\n      data: buffer.join(\"\"),\n      xfa\n    }];\n  }\n  async _saveRadioButton(evaluator, task, annotationStorage) {\n    if (!annotationStorage) {\n      return null;\n    }\n    const storageEntry = annotationStorage.get(this.data.id);\n    let rotation = storageEntry?.rotation,\n      value = storageEntry?.value;\n    if (rotation === undefined) {\n      if (value === undefined) {\n        return null;\n      }\n      const defaultValue = this.data.fieldValue === this.data.buttonValue;\n      if (defaultValue === value) {\n        return null;\n      }\n    }\n    const dict = evaluator.xref.fetchIfRef(this.ref);\n    if (!(dict instanceof Dict)) {\n      return null;\n    }\n    if (value === undefined) {\n      value = this.data.fieldValue === this.data.buttonValue;\n    }\n    if (rotation === undefined) {\n      rotation = this.rotation;\n    }\n    const xfa = {\n      path: this.data.fieldName,\n      value: value ? this.data.buttonValue : \"\"\n    };\n    const name = Name.get(value ? this.data.buttonValue : \"Off\");\n    const buffer = [];\n    let parentData = null;\n    if (value) {\n      if (this.parent instanceof Ref) {\n        const parent = evaluator.xref.fetch(this.parent);\n        parent.set(\"V\", name);\n        await writeObject(this.parent, parent, buffer, evaluator.xref);\n        parentData = buffer.join(\"\");\n        buffer.length = 0;\n      } else if (this.parent instanceof Dict) {\n        this.parent.set(\"V\", name);\n      }\n    }\n    dict.set(\"AS\", name);\n    dict.set(\"M\", `D:${getModificationDate()}`);\n    const maybeMK = this._getMKDict(rotation);\n    if (maybeMK) {\n      dict.set(\"MK\", maybeMK);\n    }\n    await writeObject(this.ref, dict, buffer, evaluator.xref);\n    const newRefs = [{\n      ref: this.ref,\n      data: buffer.join(\"\"),\n      xfa\n    }];\n    if (parentData) {\n      newRefs.push({\n        ref: this.parent,\n        data: parentData,\n        xfa: null\n      });\n    }\n    return newRefs;\n  }\n  _getDefaultCheckedAppearance(params, type) {\n    const width = this.data.rect[2] - this.data.rect[0];\n    const height = this.data.rect[3] - this.data.rect[1];\n    const bbox = [0, 0, width, height];\n    const FONT_RATIO = 0.8;\n    const fontSize = Math.min(width, height) * FONT_RATIO;\n    let metrics, char;\n    if (type === \"check\") {\n      metrics = {\n        width: 0.755 * fontSize,\n        height: 0.705 * fontSize\n      };\n      char = \"\\x33\";\n    } else if (type === \"disc\") {\n      metrics = {\n        width: 0.791 * fontSize,\n        height: 0.705 * fontSize\n      };\n      char = \"\\x6C\";\n    } else {\n      unreachable(`_getDefaultCheckedAppearance - unsupported type: ${type}`);\n    }\n    const xShift = numberToString((width - metrics.width) / 2);\n    const yShift = numberToString((height - metrics.height) / 2);\n    const appearance = `q BT /PdfJsZaDb ${fontSize} Tf 0 g ${xShift} ${yShift} Td (${char}) Tj ET Q`;\n    const appearanceStreamDict = new Dict(params.xref);\n    appearanceStreamDict.set(\"FormType\", 1);\n    appearanceStreamDict.set(\"Subtype\", Name.get(\"Form\"));\n    appearanceStreamDict.set(\"Type\", Name.get(\"XObject\"));\n    appearanceStreamDict.set(\"BBox\", bbox);\n    appearanceStreamDict.set(\"Matrix\", [1, 0, 0, 1, 0, 0]);\n    appearanceStreamDict.set(\"Length\", appearance.length);\n    const resources = new Dict(params.xref);\n    const font = new Dict(params.xref);\n    font.set(\"PdfJsZaDb\", this.fallbackFontDict);\n    resources.set(\"Font\", font);\n    appearanceStreamDict.set(\"Resources\", resources);\n    this.checkedAppearance = new StringStream(appearance);\n    this.checkedAppearance.dict = appearanceStreamDict;\n    this._streams.push(this.checkedAppearance);\n  }\n  _processCheckBox(params) {\n    const customAppearance = params.dict.get(\"AP\");\n    if (!(customAppearance instanceof Dict)) {\n      return;\n    }\n    const normalAppearance = customAppearance.get(\"N\");\n    if (!(normalAppearance instanceof Dict)) {\n      return;\n    }\n    const asValue = this._decodeFormValue(params.dict.get(\"AS\"));\n    if (typeof asValue === \"string\") {\n      this.data.fieldValue = asValue;\n    }\n    const yes = this.data.fieldValue !== null && this.data.fieldValue !== \"Off\" ? this.data.fieldValue : \"Yes\";\n    const exportValues = normalAppearance.getKeys();\n    if (exportValues.length === 0) {\n      exportValues.push(\"Off\", yes);\n    } else if (exportValues.length === 1) {\n      if (exportValues[0] === \"Off\") {\n        exportValues.push(yes);\n      } else {\n        exportValues.unshift(\"Off\");\n      }\n    } else if (exportValues.includes(yes)) {\n      exportValues.length = 0;\n      exportValues.push(\"Off\", yes);\n    } else {\n      const otherYes = exportValues.find(v => v !== \"Off\");\n      exportValues.length = 0;\n      exportValues.push(\"Off\", otherYes);\n    }\n    if (!exportValues.includes(this.data.fieldValue)) {\n      this.data.fieldValue = \"Off\";\n    }\n    this.data.exportValue = exportValues[1];\n    const checkedAppearance = normalAppearance.get(this.data.exportValue);\n    this.checkedAppearance = checkedAppearance instanceof BaseStream ? checkedAppearance : null;\n    const uncheckedAppearance = normalAppearance.get(\"Off\");\n    this.uncheckedAppearance = uncheckedAppearance instanceof BaseStream ? uncheckedAppearance : null;\n    if (this.checkedAppearance) {\n      this._streams.push(this.checkedAppearance);\n    } else {\n      this._getDefaultCheckedAppearance(params, \"check\");\n    }\n    if (this.uncheckedAppearance) {\n      this._streams.push(this.uncheckedAppearance);\n    }\n    this._fallbackFontDict = this.fallbackFontDict;\n    if (this.data.defaultFieldValue === null) {\n      this.data.defaultFieldValue = \"Off\";\n    }\n  }\n  _processRadioButton(params) {\n    this.data.buttonValue = null;\n    const fieldParent = params.dict.get(\"Parent\");\n    if (fieldParent instanceof Dict) {\n      this.parent = params.dict.getRaw(\"Parent\");\n      const fieldParentValue = fieldParent.get(\"V\");\n      if (fieldParentValue instanceof Name) {\n        this.data.fieldValue = this._decodeFormValue(fieldParentValue);\n      }\n    }\n    const appearanceStates = params.dict.get(\"AP\");\n    if (!(appearanceStates instanceof Dict)) {\n      return;\n    }\n    const normalAppearance = appearanceStates.get(\"N\");\n    if (!(normalAppearance instanceof Dict)) {\n      return;\n    }\n    for (const key of normalAppearance.getKeys()) {\n      if (key !== \"Off\") {\n        this.data.buttonValue = this._decodeFormValue(key);\n        break;\n      }\n    }\n    const checkedAppearance = normalAppearance.get(this.data.buttonValue);\n    this.checkedAppearance = checkedAppearance instanceof BaseStream ? checkedAppearance : null;\n    const uncheckedAppearance = normalAppearance.get(\"Off\");\n    this.uncheckedAppearance = uncheckedAppearance instanceof BaseStream ? uncheckedAppearance : null;\n    if (this.checkedAppearance) {\n      this._streams.push(this.checkedAppearance);\n    } else {\n      this._getDefaultCheckedAppearance(params, \"disc\");\n    }\n    if (this.uncheckedAppearance) {\n      this._streams.push(this.uncheckedAppearance);\n    }\n    this._fallbackFontDict = this.fallbackFontDict;\n    if (this.data.defaultFieldValue === null) {\n      this.data.defaultFieldValue = \"Off\";\n    }\n  }\n  _processPushButton(params) {\n    const {\n      dict,\n      annotationGlobals\n    } = params;\n    if (!dict.has(\"A\") && !dict.has(\"AA\") && !this.data.alternativeText) {\n      warn(\"Push buttons without action dictionaries are not supported\");\n      return;\n    }\n    this.data.isTooltipOnly = !dict.has(\"A\") && !dict.has(\"AA\");\n    Catalog.parseDestDictionary({\n      destDict: dict,\n      resultObj: this.data,\n      docBaseUrl: annotationGlobals.baseUrl,\n      docAttachments: annotationGlobals.attachments\n    });\n  }\n  getFieldObject() {\n    let type = \"button\";\n    let exportValues;\n    if (this.data.checkBox) {\n      type = \"checkbox\";\n      exportValues = this.data.exportValue;\n    } else if (this.data.radioButton) {\n      type = \"radiobutton\";\n      exportValues = this.data.buttonValue;\n    }\n    return {\n      id: this.data.id,\n      value: this.data.fieldValue || \"Off\",\n      defaultValue: this.data.defaultFieldValue,\n      exportValues,\n      editable: !this.data.readOnly,\n      name: this.data.fieldName,\n      rect: this.data.rect,\n      hidden: this.data.hidden,\n      actions: this.data.actions,\n      page: this.data.pageIndex,\n      strokeColor: this.data.borderColor,\n      fillColor: this.data.backgroundColor,\n      rotation: this.rotation,\n      type\n    };\n  }\n  get fallbackFontDict() {\n    const dict = new Dict();\n    dict.set(\"BaseFont\", Name.get(\"ZapfDingbats\"));\n    dict.set(\"Type\", Name.get(\"FallbackType\"));\n    dict.set(\"Subtype\", Name.get(\"FallbackType\"));\n    dict.set(\"Encoding\", Name.get(\"ZapfDingbatsEncoding\"));\n    return shadow(this, \"fallbackFontDict\", dict);\n  }\n}\nclass ChoiceWidgetAnnotation extends WidgetAnnotation {\n  constructor(params) {\n    super(params);\n    const {\n      dict,\n      xref\n    } = params;\n    this.indices = dict.getArray(\"I\");\n    this.hasIndices = Array.isArray(this.indices) && this.indices.length > 0;\n    this.data.options = [];\n    const options = getInheritableProperty({\n      dict,\n      key: \"Opt\"\n    });\n    if (Array.isArray(options)) {\n      for (let i = 0, ii = options.length; i < ii; i++) {\n        const option = xref.fetchIfRef(options[i]);\n        const isOptionArray = Array.isArray(option);\n        this.data.options[i] = {\n          exportValue: this._decodeFormValue(isOptionArray ? xref.fetchIfRef(option[0]) : option),\n          displayValue: this._decodeFormValue(isOptionArray ? xref.fetchIfRef(option[1]) : option)\n        };\n      }\n    }\n    if (!this.hasIndices) {\n      if (typeof this.data.fieldValue === \"string\") {\n        this.data.fieldValue = [this.data.fieldValue];\n      } else if (!this.data.fieldValue) {\n        this.data.fieldValue = [];\n      }\n    } else {\n      this.data.fieldValue = [];\n      const ii = this.data.options.length;\n      for (const i of this.indices) {\n        if (Number.isInteger(i) && i >= 0 && i < ii) {\n          this.data.fieldValue.push(this.data.options[i].exportValue);\n        }\n      }\n    }\n    this.data.combo = this.hasFieldFlag(AnnotationFieldFlag.COMBO);\n    this.data.multiSelect = this.hasFieldFlag(AnnotationFieldFlag.MULTISELECT);\n    this._hasText = true;\n  }\n  getFieldObject() {\n    const type = this.data.combo ? \"combobox\" : \"listbox\";\n    const value = this.data.fieldValue.length > 0 ? this.data.fieldValue[0] : null;\n    return {\n      id: this.data.id,\n      value,\n      defaultValue: this.data.defaultFieldValue,\n      editable: !this.data.readOnly,\n      name: this.data.fieldName,\n      rect: this.data.rect,\n      numItems: this.data.fieldValue.length,\n      multipleSelection: this.data.multiSelect,\n      hidden: this.data.hidden,\n      actions: this.data.actions,\n      items: this.data.options,\n      page: this.data.pageIndex,\n      strokeColor: this.data.borderColor,\n      fillColor: this.data.backgroundColor,\n      rotation: this.rotation,\n      type\n    };\n  }\n  amendSavedDict(annotationStorage, dict) {\n    if (!this.hasIndices) {\n      return;\n    }\n    let values = annotationStorage?.get(this.data.id)?.value;\n    if (!Array.isArray(values)) {\n      values = [values];\n    }\n    const indices = [];\n    const {\n      options\n    } = this.data;\n    for (let i = 0, j = 0, ii = options.length; i < ii; i++) {\n      if (options[i].exportValue === values[j]) {\n        indices.push(i);\n        j += 1;\n      }\n    }\n    dict.set(\"I\", indices);\n  }\n  async _getAppearance(evaluator, task, intent, annotationStorage) {\n    if (this.data.combo) {\n      return super._getAppearance(evaluator, task, intent, annotationStorage);\n    }\n    let exportedValue, rotation;\n    const storageEntry = annotationStorage?.get(this.data.id);\n    if (storageEntry) {\n      rotation = storageEntry.rotation;\n      exportedValue = storageEntry.value;\n    }\n    if (rotation === undefined && exportedValue === undefined && !this._needAppearances) {\n      return null;\n    }\n    if (exportedValue === undefined) {\n      exportedValue = this.data.fieldValue;\n    } else if (!Array.isArray(exportedValue)) {\n      exportedValue = [exportedValue];\n    }\n    const defaultPadding = 1;\n    const defaultHPadding = 2;\n    let totalHeight = this.data.rect[3] - this.data.rect[1];\n    let totalWidth = this.data.rect[2] - this.data.rect[0];\n    if (rotation === 90 || rotation === 270) {\n      [totalWidth, totalHeight] = [totalHeight, totalWidth];\n    }\n    const lineCount = this.data.options.length;\n    const valueIndices = [];\n    for (let i = 0; i < lineCount; i++) {\n      const {\n        exportValue\n      } = this.data.options[i];\n      if (exportedValue.includes(exportValue)) {\n        valueIndices.push(i);\n      }\n    }\n    if (!this._defaultAppearance) {\n      this.data.defaultAppearanceData = parseDefaultAppearance(this._defaultAppearance = \"/Helvetica 0 Tf 0 g\");\n    }\n    const font = await WidgetAnnotation._getFontData(evaluator, task, this.data.defaultAppearanceData, this._fieldResources.mergedResources);\n    let defaultAppearance;\n    let {\n      fontSize\n    } = this.data.defaultAppearanceData;\n    if (!fontSize) {\n      const lineHeight = (totalHeight - defaultPadding) / lineCount;\n      let lineWidth = -1;\n      let value;\n      for (const {\n        displayValue\n      } of this.data.options) {\n        const width = this._getTextWidth(displayValue, font);\n        if (width > lineWidth) {\n          lineWidth = width;\n          value = displayValue;\n        }\n      }\n      [defaultAppearance, fontSize] = this._computeFontSize(lineHeight, totalWidth - 2 * defaultHPadding, value, font, -1);\n    } else {\n      defaultAppearance = this._defaultAppearance;\n    }\n    const lineHeight = fontSize * LINE_FACTOR;\n    const vPadding = (lineHeight - fontSize) / 2;\n    const numberOfVisibleLines = Math.floor(totalHeight / lineHeight);\n    let firstIndex = 0;\n    if (valueIndices.length > 0) {\n      const minIndex = Math.min(...valueIndices);\n      const maxIndex = Math.max(...valueIndices);\n      firstIndex = Math.max(0, maxIndex - numberOfVisibleLines + 1);\n      if (firstIndex > minIndex) {\n        firstIndex = minIndex;\n      }\n    }\n    const end = Math.min(firstIndex + numberOfVisibleLines + 1, lineCount);\n    const buf = [\"/Tx BMC q\", `1 1 ${totalWidth} ${totalHeight} re W n`];\n    if (valueIndices.length) {\n      buf.push(\"0.600006 0.756866 0.854904 rg\");\n      for (const index of valueIndices) {\n        if (firstIndex <= index && index < end) {\n          buf.push(`1 ${totalHeight - (index - firstIndex + 1) * lineHeight} ${totalWidth} ${lineHeight} re f`);\n        }\n      }\n    }\n    buf.push(\"BT\", defaultAppearance, `1 0 0 1 0 ${totalHeight} Tm`);\n    const prevInfo = {\n      shift: 0\n    };\n    for (let i = firstIndex; i < end; i++) {\n      const {\n        displayValue\n      } = this.data.options[i];\n      const vpadding = i === firstIndex ? vPadding : 0;\n      buf.push(this._renderText(displayValue, font, fontSize, totalWidth, 0, prevInfo, defaultHPadding, -lineHeight + vpadding));\n    }\n    buf.push(\"ET Q EMC\");\n    return buf.join(\"\\n\");\n  }\n}\nclass SignatureWidgetAnnotation extends WidgetAnnotation {\n  constructor(params) {\n    super(params);\n    this.data.fieldValue = null;\n    this.data.hasOwnCanvas = this.data.noRotate;\n    this.data.noHTML = !this.data.hasOwnCanvas;\n  }\n  getFieldObject() {\n    return {\n      id: this.data.id,\n      value: null,\n      page: this.data.pageIndex,\n      type: \"signature\"\n    };\n  }\n}\nclass TextAnnotation extends MarkupAnnotation {\n  constructor(params) {\n    const DEFAULT_ICON_SIZE = 22;\n    super(params);\n    this.data.noRotate = true;\n    this.data.hasOwnCanvas = this.data.noRotate;\n    this.data.noHTML = false;\n    const {\n      dict\n    } = params;\n    this.data.annotationType = AnnotationType.TEXT;\n    if (this.data.hasAppearance) {\n      this.data.name = \"NoIcon\";\n    } else {\n      this.data.rect[1] = this.data.rect[3] - DEFAULT_ICON_SIZE;\n      this.data.rect[2] = this.data.rect[0] + DEFAULT_ICON_SIZE;\n      this.data.name = dict.has(\"Name\") ? dict.get(\"Name\").name : \"Note\";\n    }\n    if (dict.has(\"State\")) {\n      this.data.state = dict.get(\"State\") || null;\n      this.data.stateModel = dict.get(\"StateModel\") || null;\n    } else {\n      this.data.state = null;\n      this.data.stateModel = null;\n    }\n  }\n}\nclass LinkAnnotation extends Annotation {\n  constructor(params) {\n    super(params);\n    const {\n      dict,\n      annotationGlobals\n    } = params;\n    this.data.annotationType = AnnotationType.LINK;\n    this.data.noHTML = false;\n    const quadPoints = getQuadPoints(dict, this.rectangle);\n    if (quadPoints) {\n      this.data.quadPoints = quadPoints;\n    }\n    this.data.borderColor ||= this.data.color;\n    Catalog.parseDestDictionary({\n      destDict: dict,\n      resultObj: this.data,\n      docBaseUrl: annotationGlobals.baseUrl,\n      docAttachments: annotationGlobals.attachments\n    });\n  }\n}\nclass PopupAnnotation extends Annotation {\n  constructor(params) {\n    super(params);\n    const {\n      dict\n    } = params;\n    this.data.annotationType = AnnotationType.POPUP;\n    this.data.noHTML = false;\n    if (this.data.rect[0] === this.data.rect[2] || this.data.rect[1] === this.data.rect[3]) {\n      this.data.rect = null;\n    }\n    let parentItem = dict.get(\"Parent\");\n    if (!parentItem) {\n      warn(\"Popup annotation has a missing or invalid parent annotation.\");\n      return;\n    }\n    const parentRect = parentItem.getArray(\"Rect\");\n    this.data.parentRect = Array.isArray(parentRect) && parentRect.length === 4 ? Util.normalizeRect(parentRect) : null;\n    const rt = parentItem.get(\"RT\");\n    if (isName(rt, AnnotationReplyType.GROUP)) {\n      parentItem = parentItem.get(\"IRT\");\n    }\n    if (!parentItem.has(\"M\")) {\n      this.data.modificationDate = null;\n    } else {\n      this.setModificationDate(parentItem.get(\"M\"));\n      this.data.modificationDate = this.modificationDate;\n    }\n    if (!parentItem.has(\"C\")) {\n      this.data.color = null;\n    } else {\n      this.setColor(parentItem.getArray(\"C\"));\n      this.data.color = this.color;\n    }\n    if (!this.viewable) {\n      const parentFlags = parentItem.get(\"F\");\n      if (this._isViewable(parentFlags)) {\n        this.setFlags(parentFlags);\n      }\n    }\n    this.setTitle(parentItem.get(\"T\"));\n    this.data.titleObj = this._title;\n    this.setContents(parentItem.get(\"Contents\"));\n    this.data.contentsObj = this._contents;\n    if (parentItem.has(\"RC\")) {\n      this.data.richText = XFAFactory.getRichTextAsHtml(parentItem.get(\"RC\"));\n    }\n    this.data.open = !!dict.get(\"Open\");\n  }\n}\nclass FreeTextAnnotation extends MarkupAnnotation {\n  constructor(params) {\n    super(params);\n    this.data.hasOwnCanvas = !this.data.noHTML;\n    this.data.noHTML = false;\n    const {\n      evaluatorOptions,\n      xref\n    } = params;\n    this.data.annotationType = AnnotationType.FREETEXT;\n    this.setDefaultAppearance(params);\n    this._hasAppearance = !!this.appearance;\n    if (this._hasAppearance) {\n      const {\n        fontColor,\n        fontSize\n      } = parseAppearanceStream(this.appearance, evaluatorOptions, xref);\n      this.data.defaultAppearanceData.fontColor = fontColor;\n      this.data.defaultAppearanceData.fontSize = fontSize || 10;\n    } else {\n      this.data.defaultAppearanceData.fontSize ||= 10;\n      const {\n        fontColor,\n        fontSize\n      } = this.data.defaultAppearanceData;\n      if (this._contents.str) {\n        this.data.textContent = this._contents.str.split(/\\r\\n?|\\n/).map(line => line.trimEnd());\n        const {\n          coords,\n          bbox,\n          matrix\n        } = FakeUnicodeFont.getFirstPositionInfo(this.rectangle, this.rotation, fontSize);\n        this.data.textPosition = this._transformPoint(coords, bbox, matrix);\n      }\n      if (this._isOffscreenCanvasSupported) {\n        const strokeAlpha = params.dict.get(\"CA\");\n        const fakeUnicodeFont = new FakeUnicodeFont(xref, \"sans-serif\");\n        this.appearance = fakeUnicodeFont.createAppearance(this._contents.str, this.rectangle, this.rotation, fontSize, fontColor, strokeAlpha);\n        this._streams.push(this.appearance);\n      } else {\n        warn(\"FreeTextAnnotation: OffscreenCanvas is not supported, annotation may not render correctly.\");\n      }\n    }\n  }\n  get hasTextContent() {\n    return this._hasAppearance;\n  }\n  static createNewDict(annotation, xref, {\n    apRef,\n    ap\n  }) {\n    const {\n      color,\n      fontSize,\n      rect,\n      rotation,\n      user,\n      value\n    } = annotation;\n    const freetext = new Dict(xref);\n    freetext.set(\"Type\", Name.get(\"Annot\"));\n    freetext.set(\"Subtype\", Name.get(\"FreeText\"));\n    freetext.set(\"CreationDate\", `D:${getModificationDate()}`);\n    freetext.set(\"Rect\", rect);\n    const da = `/Helv ${fontSize} Tf ${getPdfColor(color, true)}`;\n    freetext.set(\"DA\", da);\n    freetext.set(\"Contents\", isAscii(value) ? value : stringToUTF16String(value, true));\n    freetext.set(\"F\", 4);\n    freetext.set(\"Border\", [0, 0, 0]);\n    freetext.set(\"Rotate\", rotation);\n    if (user) {\n      freetext.set(\"T\", isAscii(user) ? user : stringToUTF16String(user, true));\n    }\n    if (apRef || ap) {\n      const n = new Dict(xref);\n      freetext.set(\"AP\", n);\n      if (apRef) {\n        n.set(\"N\", apRef);\n      } else {\n        n.set(\"N\", ap);\n      }\n    }\n    return freetext;\n  }\n  static async createNewAppearanceStream(annotation, xref, params) {\n    const {\n      baseFontRef,\n      evaluator,\n      task\n    } = params;\n    const {\n      color,\n      fontSize,\n      rect,\n      rotation,\n      value\n    } = annotation;\n    const resources = new Dict(xref);\n    const font = new Dict(xref);\n    if (baseFontRef) {\n      font.set(\"Helv\", baseFontRef);\n    } else {\n      const baseFont = new Dict(xref);\n      baseFont.set(\"BaseFont\", Name.get(\"Helvetica\"));\n      baseFont.set(\"Type\", Name.get(\"Font\"));\n      baseFont.set(\"Subtype\", Name.get(\"Type1\"));\n      baseFont.set(\"Encoding\", Name.get(\"WinAnsiEncoding\"));\n      font.set(\"Helv\", baseFont);\n    }\n    resources.set(\"Font\", font);\n    const helv = await WidgetAnnotation._getFontData(evaluator, task, {\n      fontName: \"Helv\",\n      fontSize\n    }, resources);\n    const [x1, y1, x2, y2] = rect;\n    let w = x2 - x1;\n    let h = y2 - y1;\n    if (rotation % 180 !== 0) {\n      [w, h] = [h, w];\n    }\n    const lines = value.split(\"\\n\");\n    const scale = fontSize / 1000;\n    let totalWidth = -Infinity;\n    const encodedLines = [];\n    for (let line of lines) {\n      const encoded = helv.encodeString(line);\n      if (encoded.length > 1) {\n        return null;\n      }\n      line = encoded.join(\"\");\n      encodedLines.push(line);\n      let lineWidth = 0;\n      const glyphs = helv.charsToGlyphs(line);\n      for (const glyph of glyphs) {\n        lineWidth += glyph.width * scale;\n      }\n      totalWidth = Math.max(totalWidth, lineWidth);\n    }\n    let hscale = 1;\n    if (totalWidth > w) {\n      hscale = w / totalWidth;\n    }\n    let vscale = 1;\n    const lineHeight = LINE_FACTOR * fontSize;\n    const lineAscent = (LINE_FACTOR - LINE_DESCENT_FACTOR) * fontSize;\n    const totalHeight = lineHeight * lines.length;\n    if (totalHeight > h) {\n      vscale = h / totalHeight;\n    }\n    const fscale = Math.min(hscale, vscale);\n    const newFontSize = fontSize * fscale;\n    let firstPoint, clipBox, matrix;\n    switch (rotation) {\n      case 0:\n        matrix = [1, 0, 0, 1];\n        clipBox = [rect[0], rect[1], w, h];\n        firstPoint = [rect[0], rect[3] - lineAscent];\n        break;\n      case 90:\n        matrix = [0, 1, -1, 0];\n        clipBox = [rect[1], -rect[2], w, h];\n        firstPoint = [rect[1], -rect[0] - lineAscent];\n        break;\n      case 180:\n        matrix = [-1, 0, 0, -1];\n        clipBox = [-rect[2], -rect[3], w, h];\n        firstPoint = [-rect[2], -rect[1] - lineAscent];\n        break;\n      case 270:\n        matrix = [0, -1, 1, 0];\n        clipBox = [-rect[3], rect[0], w, h];\n        firstPoint = [-rect[3], rect[2] - lineAscent];\n        break;\n    }\n    const buffer = [\"q\", `${matrix.join(\" \")} 0 0 cm`, `${clipBox.join(\" \")} re W n`, `BT`, `${getPdfColor(color, true)}`, `0 Tc /Helv ${numberToString(newFontSize)} Tf`];\n    buffer.push(`${firstPoint.join(\" \")} Td (${escapeString(encodedLines[0])}) Tj`);\n    const vShift = numberToString(lineHeight);\n    for (let i = 1, ii = encodedLines.length; i < ii; i++) {\n      const line = encodedLines[i];\n      buffer.push(`0 -${vShift} Td (${escapeString(line)}) Tj`);\n    }\n    buffer.push(\"ET\", \"Q\");\n    const appearance = buffer.join(\"\\n\");\n    const appearanceStreamDict = new Dict(xref);\n    appearanceStreamDict.set(\"FormType\", 1);\n    appearanceStreamDict.set(\"Subtype\", Name.get(\"Form\"));\n    appearanceStreamDict.set(\"Type\", Name.get(\"XObject\"));\n    appearanceStreamDict.set(\"BBox\", rect);\n    appearanceStreamDict.set(\"Resources\", resources);\n    appearanceStreamDict.set(\"Matrix\", [1, 0, 0, 1, -rect[0], -rect[1]]);\n    const ap = new StringStream(appearance);\n    ap.dict = appearanceStreamDict;\n    return ap;\n  }\n}\nclass LineAnnotation extends MarkupAnnotation {\n  constructor(params) {\n    super(params);\n    const {\n      dict,\n      xref\n    } = params;\n    this.data.annotationType = AnnotationType.LINE;\n    this.data.hasOwnCanvas = this.data.noRotate;\n    this.data.noHTML = false;\n    const lineCoordinates = dict.getArray(\"L\");\n    this.data.lineCoordinates = Util.normalizeRect(lineCoordinates);\n    this.setLineEndings(dict.getArray(\"LE\"));\n    this.data.lineEndings = this.lineEndings;\n    if (!this.appearance) {\n      const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0];\n      const strokeAlpha = dict.get(\"CA\");\n      const interiorColor = getRgbColor(dict.getArray(\"IC\"), null);\n      const fillColor = interiorColor ? getPdfColorArray(interiorColor) : null;\n      const fillAlpha = fillColor ? strokeAlpha : null;\n      const borderWidth = this.borderStyle.width || 1,\n        borderAdjust = 2 * borderWidth;\n      const bbox = [this.data.lineCoordinates[0] - borderAdjust, this.data.lineCoordinates[1] - borderAdjust, this.data.lineCoordinates[2] + borderAdjust, this.data.lineCoordinates[3] + borderAdjust];\n      if (!Util.intersect(this.rectangle, bbox)) {\n        this.rectangle = bbox;\n      }\n      this._setDefaultAppearance({\n        xref,\n        extra: `${borderWidth} w`,\n        strokeColor,\n        fillColor,\n        strokeAlpha,\n        fillAlpha,\n        pointsCallback: (buffer, points) => {\n          buffer.push(`${lineCoordinates[0]} ${lineCoordinates[1]} m`, `${lineCoordinates[2]} ${lineCoordinates[3]} l`, \"S\");\n          return [points[0].x - borderWidth, points[1].x + borderWidth, points[3].y - borderWidth, points[1].y + borderWidth];\n        }\n      });\n    }\n  }\n}\nclass SquareAnnotation extends MarkupAnnotation {\n  constructor(params) {\n    super(params);\n    const {\n      dict,\n      xref\n    } = params;\n    this.data.annotationType = AnnotationType.SQUARE;\n    this.data.hasOwnCanvas = this.data.noRotate;\n    this.data.noHTML = false;\n    if (!this.appearance) {\n      const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0];\n      const strokeAlpha = dict.get(\"CA\");\n      const interiorColor = getRgbColor(dict.getArray(\"IC\"), null);\n      const fillColor = interiorColor ? getPdfColorArray(interiorColor) : null;\n      const fillAlpha = fillColor ? strokeAlpha : null;\n      if (this.borderStyle.width === 0 && !fillColor) {\n        return;\n      }\n      this._setDefaultAppearance({\n        xref,\n        extra: `${this.borderStyle.width} w`,\n        strokeColor,\n        fillColor,\n        strokeAlpha,\n        fillAlpha,\n        pointsCallback: (buffer, points) => {\n          const x = points[2].x + this.borderStyle.width / 2;\n          const y = points[2].y + this.borderStyle.width / 2;\n          const width = points[3].x - points[2].x - this.borderStyle.width;\n          const height = points[1].y - points[3].y - this.borderStyle.width;\n          buffer.push(`${x} ${y} ${width} ${height} re`);\n          if (fillColor) {\n            buffer.push(\"B\");\n          } else {\n            buffer.push(\"S\");\n          }\n          return [points[0].x, points[1].x, points[3].y, points[1].y];\n        }\n      });\n    }\n  }\n}\nclass CircleAnnotation extends MarkupAnnotation {\n  constructor(params) {\n    super(params);\n    const {\n      dict,\n      xref\n    } = params;\n    this.data.annotationType = AnnotationType.CIRCLE;\n    if (!this.appearance) {\n      const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0];\n      const strokeAlpha = dict.get(\"CA\");\n      const interiorColor = getRgbColor(dict.getArray(\"IC\"), null);\n      const fillColor = interiorColor ? getPdfColorArray(interiorColor) : null;\n      const fillAlpha = fillColor ? strokeAlpha : null;\n      if (this.borderStyle.width === 0 && !fillColor) {\n        return;\n      }\n      const controlPointsDistance = 4 / 3 * Math.tan(Math.PI / (2 * 4));\n      this._setDefaultAppearance({\n        xref,\n        extra: `${this.borderStyle.width} w`,\n        strokeColor,\n        fillColor,\n        strokeAlpha,\n        fillAlpha,\n        pointsCallback: (buffer, points) => {\n          const x0 = points[0].x + this.borderStyle.width / 2;\n          const y0 = points[0].y - this.borderStyle.width / 2;\n          const x1 = points[3].x - this.borderStyle.width / 2;\n          const y1 = points[3].y + this.borderStyle.width / 2;\n          const xMid = x0 + (x1 - x0) / 2;\n          const yMid = y0 + (y1 - y0) / 2;\n          const xOffset = (x1 - x0) / 2 * controlPointsDistance;\n          const yOffset = (y1 - y0) / 2 * controlPointsDistance;\n          buffer.push(`${xMid} ${y1} m`, `${xMid + xOffset} ${y1} ${x1} ${yMid + yOffset} ${x1} ${yMid} c`, `${x1} ${yMid - yOffset} ${xMid + xOffset} ${y0} ${xMid} ${y0} c`, `${xMid - xOffset} ${y0} ${x0} ${yMid - yOffset} ${x0} ${yMid} c`, `${x0} ${yMid + yOffset} ${xMid - xOffset} ${y1} ${xMid} ${y1} c`, \"h\");\n          if (fillColor) {\n            buffer.push(\"B\");\n          } else {\n            buffer.push(\"S\");\n          }\n          return [points[0].x, points[1].x, points[3].y, points[1].y];\n        }\n      });\n    }\n  }\n}\nclass PolylineAnnotation extends MarkupAnnotation {\n  constructor(params) {\n    super(params);\n    const {\n      dict,\n      xref\n    } = params;\n    this.data.annotationType = AnnotationType.POLYLINE;\n    this.data.hasOwnCanvas = this.data.noRotate;\n    this.data.noHTML = false;\n    this.data.vertices = [];\n    if (!(this instanceof PolygonAnnotation)) {\n      this.setLineEndings(dict.getArray(\"LE\"));\n      this.data.lineEndings = this.lineEndings;\n    }\n    const rawVertices = dict.getArray(\"Vertices\");\n    if (!Array.isArray(rawVertices)) {\n      return;\n    }\n    for (let i = 0, ii = rawVertices.length; i < ii; i += 2) {\n      this.data.vertices.push({\n        x: rawVertices[i],\n        y: rawVertices[i + 1]\n      });\n    }\n    if (!this.appearance) {\n      const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0];\n      const strokeAlpha = dict.get(\"CA\");\n      const borderWidth = this.borderStyle.width || 1,\n        borderAdjust = 2 * borderWidth;\n      const bbox = [Infinity, Infinity, -Infinity, -Infinity];\n      for (const vertex of this.data.vertices) {\n        bbox[0] = Math.min(bbox[0], vertex.x - borderAdjust);\n        bbox[1] = Math.min(bbox[1], vertex.y - borderAdjust);\n        bbox[2] = Math.max(bbox[2], vertex.x + borderAdjust);\n        bbox[3] = Math.max(bbox[3], vertex.y + borderAdjust);\n      }\n      if (!Util.intersect(this.rectangle, bbox)) {\n        this.rectangle = bbox;\n      }\n      this._setDefaultAppearance({\n        xref,\n        extra: `${borderWidth} w`,\n        strokeColor,\n        strokeAlpha,\n        pointsCallback: (buffer, points) => {\n          const vertices = this.data.vertices;\n          for (let i = 0, ii = vertices.length; i < ii; i++) {\n            buffer.push(`${vertices[i].x} ${vertices[i].y} ${i === 0 ? \"m\" : \"l\"}`);\n          }\n          buffer.push(\"S\");\n          return [points[0].x, points[1].x, points[3].y, points[1].y];\n        }\n      });\n    }\n  }\n}\nclass PolygonAnnotation extends PolylineAnnotation {\n  constructor(params) {\n    super(params);\n    this.data.annotationType = AnnotationType.POLYGON;\n  }\n}\nclass CaretAnnotation extends MarkupAnnotation {\n  constructor(params) {\n    super(params);\n    this.data.annotationType = AnnotationType.CARET;\n  }\n}\nclass InkAnnotation extends MarkupAnnotation {\n  constructor(params) {\n    super(params);\n    this.data.hasOwnCanvas = this.data.noRotate;\n    this.data.noHTML = false;\n    const {\n      dict,\n      xref\n    } = params;\n    this.data.annotationType = AnnotationType.INK;\n    this.data.inkLists = [];\n    const rawInkLists = dict.getArray(\"InkList\");\n    if (!Array.isArray(rawInkLists)) {\n      return;\n    }\n    for (let i = 0, ii = rawInkLists.length; i < ii; ++i) {\n      this.data.inkLists.push([]);\n      for (let j = 0, jj = rawInkLists[i].length; j < jj; j += 2) {\n        this.data.inkLists[i].push({\n          x: xref.fetchIfRef(rawInkLists[i][j]),\n          y: xref.fetchIfRef(rawInkLists[i][j + 1])\n        });\n      }\n    }\n    if (!this.appearance) {\n      const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0];\n      const strokeAlpha = dict.get(\"CA\");\n      const borderWidth = this.borderStyle.width || 1,\n        borderAdjust = 2 * borderWidth;\n      const bbox = [Infinity, Infinity, -Infinity, -Infinity];\n      for (const inkLists of this.data.inkLists) {\n        for (const vertex of inkLists) {\n          bbox[0] = Math.min(bbox[0], vertex.x - borderAdjust);\n          bbox[1] = Math.min(bbox[1], vertex.y - borderAdjust);\n          bbox[2] = Math.max(bbox[2], vertex.x + borderAdjust);\n          bbox[3] = Math.max(bbox[3], vertex.y + borderAdjust);\n        }\n      }\n      if (!Util.intersect(this.rectangle, bbox)) {\n        this.rectangle = bbox;\n      }\n      this._setDefaultAppearance({\n        xref,\n        extra: `${borderWidth} w`,\n        strokeColor,\n        strokeAlpha,\n        pointsCallback: (buffer, points) => {\n          for (const inkList of this.data.inkLists) {\n            for (let i = 0, ii = inkList.length; i < ii; i++) {\n              buffer.push(`${inkList[i].x} ${inkList[i].y} ${i === 0 ? \"m\" : \"l\"}`);\n            }\n            buffer.push(\"S\");\n          }\n          return [points[0].x, points[1].x, points[3].y, points[1].y];\n        }\n      });\n    }\n  }\n  static createNewDict(annotation, xref, {\n    apRef,\n    ap\n  }) {\n    const {\n      color,\n      opacity,\n      paths,\n      outlines,\n      rect,\n      rotation,\n      thickness\n    } = annotation;\n    const ink = new Dict(xref);\n    ink.set(\"Type\", Name.get(\"Annot\"));\n    ink.set(\"Subtype\", Name.get(\"Ink\"));\n    ink.set(\"CreationDate\", `D:${getModificationDate()}`);\n    ink.set(\"Rect\", rect);\n    ink.set(\"InkList\", outlines?.points || paths.map(p => p.points));\n    ink.set(\"F\", 4);\n    ink.set(\"Rotate\", rotation);\n    if (outlines) {\n      ink.set(\"IT\", Name.get(\"InkHighlight\"));\n    }\n    const bs = new Dict(xref);\n    ink.set(\"BS\", bs);\n    bs.set(\"W\", thickness);\n    ink.set(\"C\", Array.from(color, c => c / 255));\n    ink.set(\"CA\", opacity);\n    const n = new Dict(xref);\n    ink.set(\"AP\", n);\n    if (apRef) {\n      n.set(\"N\", apRef);\n    } else {\n      n.set(\"N\", ap);\n    }\n    return ink;\n  }\n  static async createNewAppearanceStream(annotation, xref, params) {\n    if (annotation.outlines) {\n      return this.createNewAppearanceStreamForHighlight(annotation, xref, params);\n    }\n    const {\n      color,\n      rect,\n      paths,\n      thickness,\n      opacity\n    } = annotation;\n    const appearanceBuffer = [`${thickness} w 1 J 1 j`, `${getPdfColor(color, false)}`];\n    if (opacity !== 1) {\n      appearanceBuffer.push(\"/R0 gs\");\n    }\n    const buffer = [];\n    for (const {\n      bezier\n    } of paths) {\n      buffer.length = 0;\n      buffer.push(`${numberToString(bezier[0])} ${numberToString(bezier[1])} m`);\n      if (bezier.length === 2) {\n        buffer.push(`${numberToString(bezier[0])} ${numberToString(bezier[1])} l S`);\n      } else {\n        for (let i = 2, ii = bezier.length; i < ii; i += 6) {\n          const curve = bezier.slice(i, i + 6).map(numberToString).join(\" \");\n          buffer.push(`${curve} c`);\n        }\n        buffer.push(\"S\");\n      }\n      appearanceBuffer.push(buffer.join(\"\\n\"));\n    }\n    const appearance = appearanceBuffer.join(\"\\n\");\n    const appearanceStreamDict = new Dict(xref);\n    appearanceStreamDict.set(\"FormType\", 1);\n    appearanceStreamDict.set(\"Subtype\", Name.get(\"Form\"));\n    appearanceStreamDict.set(\"Type\", Name.get(\"XObject\"));\n    appearanceStreamDict.set(\"BBox\", rect);\n    appearanceStreamDict.set(\"Length\", appearance.length);\n    if (opacity !== 1) {\n      const resources = new Dict(xref);\n      const extGState = new Dict(xref);\n      const r0 = new Dict(xref);\n      r0.set(\"CA\", opacity);\n      r0.set(\"Type\", Name.get(\"ExtGState\"));\n      extGState.set(\"R0\", r0);\n      resources.set(\"ExtGState\", extGState);\n      appearanceStreamDict.set(\"Resources\", resources);\n    }\n    const ap = new StringStream(appearance);\n    ap.dict = appearanceStreamDict;\n    return ap;\n  }\n  static async createNewAppearanceStreamForHighlight(annotation, xref, params) {\n    const {\n      color,\n      rect,\n      outlines: {\n        outline\n      },\n      opacity\n    } = annotation;\n    const appearanceBuffer = [`${getPdfColor(color, true)}`, \"/R0 gs\"];\n    appearanceBuffer.push(`${numberToString(outline[4])} ${numberToString(outline[5])} m`);\n    for (let i = 6, ii = outline.length; i < ii; i += 6) {\n      if (isNaN(outline[i]) || outline[i] === null) {\n        appearanceBuffer.push(`${numberToString(outline[i + 4])} ${numberToString(outline[i + 5])} l`);\n      } else {\n        const curve = outline.slice(i, i + 6).map(numberToString).join(\" \");\n        appearanceBuffer.push(`${curve} c`);\n      }\n    }\n    appearanceBuffer.push(\"h f\");\n    const appearance = appearanceBuffer.join(\"\\n\");\n    const appearanceStreamDict = new Dict(xref);\n    appearanceStreamDict.set(\"FormType\", 1);\n    appearanceStreamDict.set(\"Subtype\", Name.get(\"Form\"));\n    appearanceStreamDict.set(\"Type\", Name.get(\"XObject\"));\n    appearanceStreamDict.set(\"BBox\", rect);\n    appearanceStreamDict.set(\"Length\", appearance.length);\n    const resources = new Dict(xref);\n    const extGState = new Dict(xref);\n    resources.set(\"ExtGState\", extGState);\n    appearanceStreamDict.set(\"Resources\", resources);\n    const r0 = new Dict(xref);\n    extGState.set(\"R0\", r0);\n    r0.set(\"BM\", Name.get(\"Multiply\"));\n    if (opacity !== 1) {\n      r0.set(\"ca\", opacity);\n      r0.set(\"Type\", Name.get(\"ExtGState\"));\n    }\n    const ap = new StringStream(appearance);\n    ap.dict = appearanceStreamDict;\n    return ap;\n  }\n}\nclass HighlightAnnotation extends MarkupAnnotation {\n  constructor(params) {\n    super(params);\n    const {\n      dict,\n      xref\n    } = params;\n    this.data.annotationType = AnnotationType.HIGHLIGHT;\n    const quadPoints = this.data.quadPoints = getQuadPoints(dict, null);\n    if (quadPoints) {\n      const resources = this.appearance?.dict.get(\"Resources\");\n      if (!this.appearance || !resources?.has(\"ExtGState\")) {\n        if (this.appearance) {\n          warn(\"HighlightAnnotation - ignoring built-in appearance stream.\");\n        }\n        const fillColor = this.color ? getPdfColorArray(this.color) : [1, 1, 0];\n        const fillAlpha = dict.get(\"CA\");\n        this._setDefaultAppearance({\n          xref,\n          fillColor,\n          blendMode: \"Multiply\",\n          fillAlpha,\n          pointsCallback: (buffer, points) => {\n            buffer.push(`${points[0].x} ${points[0].y} m`, `${points[1].x} ${points[1].y} l`, `${points[3].x} ${points[3].y} l`, `${points[2].x} ${points[2].y} l`, \"f\");\n            return [points[0].x, points[1].x, points[3].y, points[1].y];\n          }\n        });\n      }\n    } else {\n      this.data.popupRef = null;\n    }\n  }\n  static createNewDict(annotation, xref, {\n    apRef,\n    ap\n  }) {\n    const {\n      color,\n      opacity,\n      rect,\n      rotation,\n      user,\n      quadPoints\n    } = annotation;\n    const highlight = new Dict(xref);\n    highlight.set(\"Type\", Name.get(\"Annot\"));\n    highlight.set(\"Subtype\", Name.get(\"Highlight\"));\n    highlight.set(\"CreationDate\", `D:${getModificationDate()}`);\n    highlight.set(\"Rect\", rect);\n    highlight.set(\"F\", 4);\n    highlight.set(\"Border\", [0, 0, 0]);\n    highlight.set(\"Rotate\", rotation);\n    highlight.set(\"QuadPoints\", quadPoints);\n    highlight.set(\"C\", Array.from(color, c => c / 255));\n    highlight.set(\"CA\", opacity);\n    if (user) {\n      highlight.set(\"T\", isAscii(user) ? user : stringToUTF16String(user, true));\n    }\n    if (apRef || ap) {\n      const n = new Dict(xref);\n      highlight.set(\"AP\", n);\n      n.set(\"N\", apRef || ap);\n    }\n    return highlight;\n  }\n  static async createNewAppearanceStream(annotation, xref, params) {\n    const {\n      color,\n      rect,\n      outlines,\n      opacity\n    } = annotation;\n    const appearanceBuffer = [`${getPdfColor(color, true)}`, \"/R0 gs\"];\n    const buffer = [];\n    for (const outline of outlines) {\n      buffer.length = 0;\n      buffer.push(`${numberToString(outline[0])} ${numberToString(outline[1])} m`);\n      for (let i = 2, ii = outline.length; i < ii; i += 2) {\n        buffer.push(`${numberToString(outline[i])} ${numberToString(outline[i + 1])} l`);\n      }\n      buffer.push(\"h\");\n      appearanceBuffer.push(buffer.join(\"\\n\"));\n    }\n    appearanceBuffer.push(\"f*\");\n    const appearance = appearanceBuffer.join(\"\\n\");\n    const appearanceStreamDict = new Dict(xref);\n    appearanceStreamDict.set(\"FormType\", 1);\n    appearanceStreamDict.set(\"Subtype\", Name.get(\"Form\"));\n    appearanceStreamDict.set(\"Type\", Name.get(\"XObject\"));\n    appearanceStreamDict.set(\"BBox\", rect);\n    appearanceStreamDict.set(\"Length\", appearance.length);\n    const resources = new Dict(xref);\n    const extGState = new Dict(xref);\n    resources.set(\"ExtGState\", extGState);\n    appearanceStreamDict.set(\"Resources\", resources);\n    const r0 = new Dict(xref);\n    extGState.set(\"R0\", r0);\n    r0.set(\"BM\", Name.get(\"Multiply\"));\n    if (opacity !== 1) {\n      r0.set(\"ca\", opacity);\n      r0.set(\"Type\", Name.get(\"ExtGState\"));\n    }\n    const ap = new StringStream(appearance);\n    ap.dict = appearanceStreamDict;\n    return ap;\n  }\n}\nclass UnderlineAnnotation extends MarkupAnnotation {\n  constructor(params) {\n    super(params);\n    const {\n      dict,\n      xref\n    } = params;\n    this.data.annotationType = AnnotationType.UNDERLINE;\n    const quadPoints = this.data.quadPoints = getQuadPoints(dict, null);\n    if (quadPoints) {\n      if (!this.appearance) {\n        const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0];\n        const strokeAlpha = dict.get(\"CA\");\n        this._setDefaultAppearance({\n          xref,\n          extra: \"[] 0 d 0.571 w\",\n          strokeColor,\n          strokeAlpha,\n          pointsCallback: (buffer, points) => {\n            buffer.push(`${points[2].x} ${points[2].y + 1.3} m`, `${points[3].x} ${points[3].y + 1.3} l`, \"S\");\n            return [points[0].x, points[1].x, points[3].y, points[1].y];\n          }\n        });\n      }\n    } else {\n      this.data.popupRef = null;\n    }\n  }\n}\nclass SquigglyAnnotation extends MarkupAnnotation {\n  constructor(params) {\n    super(params);\n    const {\n      dict,\n      xref\n    } = params;\n    this.data.annotationType = AnnotationType.SQUIGGLY;\n    const quadPoints = this.data.quadPoints = getQuadPoints(dict, null);\n    if (quadPoints) {\n      if (!this.appearance) {\n        const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0];\n        const strokeAlpha = dict.get(\"CA\");\n        this._setDefaultAppearance({\n          xref,\n          extra: \"[] 0 d 1 w\",\n          strokeColor,\n          strokeAlpha,\n          pointsCallback: (buffer, points) => {\n            const dy = (points[0].y - points[2].y) / 6;\n            let shift = dy;\n            let x = points[2].x;\n            const y = points[2].y;\n            const xEnd = points[3].x;\n            buffer.push(`${x} ${y + shift} m`);\n            do {\n              x += 2;\n              shift = shift === 0 ? dy : 0;\n              buffer.push(`${x} ${y + shift} l`);\n            } while (x < xEnd);\n            buffer.push(\"S\");\n            return [points[2].x, xEnd, y - 2 * dy, y + 2 * dy];\n          }\n        });\n      }\n    } else {\n      this.data.popupRef = null;\n    }\n  }\n}\nclass StrikeOutAnnotation extends MarkupAnnotation {\n  constructor(params) {\n    super(params);\n    const {\n      dict,\n      xref\n    } = params;\n    this.data.annotationType = AnnotationType.STRIKEOUT;\n    const quadPoints = this.data.quadPoints = getQuadPoints(dict, null);\n    if (quadPoints) {\n      if (!this.appearance) {\n        const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0];\n        const strokeAlpha = dict.get(\"CA\");\n        this._setDefaultAppearance({\n          xref,\n          extra: \"[] 0 d 1 w\",\n          strokeColor,\n          strokeAlpha,\n          pointsCallback: (buffer, points) => {\n            buffer.push(`${(points[0].x + points[2].x) / 2} ` + `${(points[0].y + points[2].y) / 2} m`, `${(points[1].x + points[3].x) / 2} ` + `${(points[1].y + points[3].y) / 2} l`, \"S\");\n            return [points[0].x, points[1].x, points[3].y, points[1].y];\n          }\n        });\n      }\n    } else {\n      this.data.popupRef = null;\n    }\n  }\n}\nclass StampAnnotation extends MarkupAnnotation {\n  constructor(params) {\n    super(params);\n    this.data.annotationType = AnnotationType.STAMP;\n    this.data.hasOwnCanvas = this.data.noRotate;\n    this.data.noHTML = false;\n  }\n  static async createImage(bitmap, xref) {\n    const {\n      width,\n      height\n    } = bitmap;\n    const canvas = new OffscreenCanvas(width, height);\n    const ctx = canvas.getContext(\"2d\", {\n      alpha: true\n    });\n    ctx.drawImage(bitmap, 0, 0);\n    const data = ctx.getImageData(0, 0, width, height).data;\n    const buf32 = new Uint32Array(data.buffer);\n    const hasAlpha = buf32.some(FeatureTest.isLittleEndian ? x => x >>> 24 !== 0xff : x => (x & 0xff) !== 0xff);\n    if (hasAlpha) {\n      ctx.fillStyle = \"white\";\n      ctx.fillRect(0, 0, width, height);\n      ctx.drawImage(bitmap, 0, 0);\n    }\n    const jpegBufferPromise = canvas.convertToBlob({\n      type: \"image/jpeg\",\n      quality: 1\n    }).then(blob => blob.arrayBuffer());\n    const xobjectName = Name.get(\"XObject\");\n    const imageName = Name.get(\"Image\");\n    const image = new Dict(xref);\n    image.set(\"Type\", xobjectName);\n    image.set(\"Subtype\", imageName);\n    image.set(\"BitsPerComponent\", 8);\n    image.set(\"ColorSpace\", Name.get(\"DeviceRGB\"));\n    image.set(\"Filter\", Name.get(\"DCTDecode\"));\n    image.set(\"BBox\", [0, 0, width, height]);\n    image.set(\"Width\", width);\n    image.set(\"Height\", height);\n    let smaskStream = null;\n    if (hasAlpha) {\n      const alphaBuffer = new Uint8Array(buf32.length);\n      if (FeatureTest.isLittleEndian) {\n        for (let i = 0, ii = buf32.length; i < ii; i++) {\n          alphaBuffer[i] = buf32[i] >>> 24;\n        }\n      } else {\n        for (let i = 0, ii = buf32.length; i < ii; i++) {\n          alphaBuffer[i] = buf32[i] & 0xff;\n        }\n      }\n      const smask = new Dict(xref);\n      smask.set(\"Type\", xobjectName);\n      smask.set(\"Subtype\", imageName);\n      smask.set(\"BitsPerComponent\", 8);\n      smask.set(\"ColorSpace\", Name.get(\"DeviceGray\"));\n      smask.set(\"Width\", width);\n      smask.set(\"Height\", height);\n      smaskStream = new Stream(alphaBuffer, 0, 0, smask);\n    }\n    const imageStream = new Stream(await jpegBufferPromise, 0, 0, image);\n    return {\n      imageStream,\n      smaskStream,\n      width,\n      height\n    };\n  }\n  static createNewDict(annotation, xref, {\n    apRef,\n    ap\n  }) {\n    const {\n      rect,\n      rotation,\n      user\n    } = annotation;\n    const stamp = new Dict(xref);\n    stamp.set(\"Type\", Name.get(\"Annot\"));\n    stamp.set(\"Subtype\", Name.get(\"Stamp\"));\n    stamp.set(\"CreationDate\", `D:${getModificationDate()}`);\n    stamp.set(\"Rect\", rect);\n    stamp.set(\"F\", 4);\n    stamp.set(\"Border\", [0, 0, 0]);\n    stamp.set(\"Rotate\", rotation);\n    if (user) {\n      stamp.set(\"T\", isAscii(user) ? user : stringToUTF16String(user, true));\n    }\n    if (apRef || ap) {\n      const n = new Dict(xref);\n      stamp.set(\"AP\", n);\n      if (apRef) {\n        n.set(\"N\", apRef);\n      } else {\n        n.set(\"N\", ap);\n      }\n    }\n    return stamp;\n  }\n  static async createNewAppearanceStream(annotation, xref, params) {\n    const {\n      rotation\n    } = annotation;\n    const {\n      imageRef,\n      width,\n      height\n    } = params.image;\n    const resources = new Dict(xref);\n    const xobject = new Dict(xref);\n    resources.set(\"XObject\", xobject);\n    xobject.set(\"Im0\", imageRef);\n    const appearance = `q ${width} 0 0 ${height} 0 0 cm /Im0 Do Q`;\n    const appearanceStreamDict = new Dict(xref);\n    appearanceStreamDict.set(\"FormType\", 1);\n    appearanceStreamDict.set(\"Subtype\", Name.get(\"Form\"));\n    appearanceStreamDict.set(\"Type\", Name.get(\"XObject\"));\n    appearanceStreamDict.set(\"BBox\", [0, 0, width, height]);\n    appearanceStreamDict.set(\"Resources\", resources);\n    if (rotation) {\n      const matrix = getRotationMatrix(rotation, width, height);\n      appearanceStreamDict.set(\"Matrix\", matrix);\n    }\n    const ap = new StringStream(appearance);\n    ap.dict = appearanceStreamDict;\n    return ap;\n  }\n}\nclass FileAttachmentAnnotation extends MarkupAnnotation {\n  constructor(params) {\n    super(params);\n    const {\n      dict,\n      xref\n    } = params;\n    const file = new FileSpec(dict.get(\"FS\"), xref);\n    this.data.annotationType = AnnotationType.FILEATTACHMENT;\n    this.data.hasOwnCanvas = this.data.noRotate;\n    this.data.noHTML = false;\n    this.data.file = file.serializable;\n    const name = dict.get(\"Name\");\n    this.data.name = name instanceof Name ? stringToPDFString(name.name) : \"PushPin\";\n    const fillAlpha = dict.get(\"ca\");\n    this.data.fillAlpha = typeof fillAlpha === \"number\" && fillAlpha >= 0 && fillAlpha <= 1 ? fillAlpha : null;\n  }\n}\n\n;// ./src/core/dataset_reader.js\n\n\n\nfunction decodeString(str) {\n  try {\n    return stringToUTF8String(str);\n  } catch (ex) {\n    warn(`UTF-8 decoding failed: \"${ex}\".`);\n    return str;\n  }\n}\nclass DatasetXMLParser extends SimpleXMLParser {\n  constructor(options) {\n    super(options);\n    this.node = null;\n  }\n  onEndElement(name) {\n    const node = super.onEndElement(name);\n    if (node && name === \"xfa:datasets\") {\n      this.node = node;\n      throw new Error(\"Aborting DatasetXMLParser.\");\n    }\n  }\n}\nclass DatasetReader {\n  constructor(data) {\n    if (data.datasets) {\n      this.node = new SimpleXMLParser({\n        hasAttributes: true\n      }).parseFromString(data.datasets).documentElement;\n    } else {\n      const parser = new DatasetXMLParser({\n        hasAttributes: true\n      });\n      try {\n        parser.parseFromString(data[\"xdp:xdp\"]);\n      } catch {}\n      this.node = parser.node;\n    }\n  }\n  getValue(path) {\n    if (!this.node || !path) {\n      return \"\";\n    }\n    const node = this.node.searchNode(parseXFAPath(path), 0);\n    if (!node) {\n      return \"\";\n    }\n    const first = node.firstChild;\n    if (first?.nodeName === \"value\") {\n      return node.children.map(child => decodeString(child.textContent));\n    }\n    return decodeString(node.textContent);\n  }\n}\n\n;// ./src/core/xref.js\n\n\n\n\n\n\nclass XRef {\n  #firstXRefStmPos = null;\n  constructor(stream, pdfManager) {\n    this.stream = stream;\n    this.pdfManager = pdfManager;\n    this.entries = [];\n    this._xrefStms = new Set();\n    this._cacheMap = new Map();\n    this._pendingRefs = new RefSet();\n    this._newPersistentRefNum = null;\n    this._newTemporaryRefNum = null;\n    this._persistentRefsCache = null;\n  }\n  getNewPersistentRef(obj) {\n    if (this._newPersistentRefNum === null) {\n      this._newPersistentRefNum = this.entries.length || 1;\n    }\n    const num = this._newPersistentRefNum++;\n    this._cacheMap.set(num, obj);\n    return Ref.get(num, 0);\n  }\n  getNewTemporaryRef() {\n    if (this._newTemporaryRefNum === null) {\n      this._newTemporaryRefNum = this.entries.length || 1;\n      if (this._newPersistentRefNum) {\n        this._persistentRefsCache = new Map();\n        for (let i = this._newTemporaryRefNum; i < this._newPersistentRefNum; i++) {\n          this._persistentRefsCache.set(i, this._cacheMap.get(i));\n          this._cacheMap.delete(i);\n        }\n      }\n    }\n    return Ref.get(this._newTemporaryRefNum++, 0);\n  }\n  resetNewTemporaryRef() {\n    this._newTemporaryRefNum = null;\n    if (this._persistentRefsCache) {\n      for (const [num, obj] of this._persistentRefsCache) {\n        this._cacheMap.set(num, obj);\n      }\n    }\n    this._persistentRefsCache = null;\n  }\n  setStartXRef(startXRef) {\n    this.startXRefQueue = [startXRef];\n  }\n  parse(recoveryMode = false) {\n    let trailerDict;\n    if (!recoveryMode) {\n      trailerDict = this.readXRef();\n    } else {\n      warn(\"Indexing all PDF objects\");\n      trailerDict = this.indexObjects();\n    }\n    trailerDict.assignXref(this);\n    this.trailer = trailerDict;\n    let encrypt;\n    try {\n      encrypt = trailerDict.get(\"Encrypt\");\n    } catch (ex) {\n      if (ex instanceof MissingDataException) {\n        throw ex;\n      }\n      warn(`XRef.parse - Invalid \"Encrypt\" reference: \"${ex}\".`);\n    }\n    if (encrypt instanceof Dict) {\n      const ids = trailerDict.get(\"ID\");\n      const fileId = ids?.length ? ids[0] : \"\";\n      encrypt.suppressEncryption = true;\n      this.encrypt = new CipherTransformFactory(encrypt, fileId, this.pdfManager.password);\n    }\n    let root;\n    try {\n      root = trailerDict.get(\"Root\");\n    } catch (ex) {\n      if (ex instanceof MissingDataException) {\n        throw ex;\n      }\n      warn(`XRef.parse - Invalid \"Root\" reference: \"${ex}\".`);\n    }\n    if (root instanceof Dict) {\n      try {\n        const pages = root.get(\"Pages\");\n        if (pages instanceof Dict) {\n          this.root = root;\n          return;\n        }\n      } catch (ex) {\n        if (ex instanceof MissingDataException) {\n          throw ex;\n        }\n        warn(`XRef.parse - Invalid \"Pages\" reference: \"${ex}\".`);\n      }\n    }\n    if (!recoveryMode) {\n      throw new XRefParseException();\n    }\n    throw new InvalidPDFException(\"Invalid Root reference.\");\n  }\n  processXRefTable(parser) {\n    if (!(\"tableState\" in this)) {\n      this.tableState = {\n        entryNum: 0,\n        streamPos: parser.lexer.stream.pos,\n        parserBuf1: parser.buf1,\n        parserBuf2: parser.buf2\n      };\n    }\n    const obj = this.readXRefTable(parser);\n    if (!isCmd(obj, \"trailer\")) {\n      throw new FormatError(\"Invalid XRef table: could not find trailer dictionary\");\n    }\n    let dict = parser.getObj();\n    if (!(dict instanceof Dict) && dict.dict) {\n      dict = dict.dict;\n    }\n    if (!(dict instanceof Dict)) {\n      throw new FormatError(\"Invalid XRef table: could not parse trailer dictionary\");\n    }\n    delete this.tableState;\n    return dict;\n  }\n  readXRefTable(parser) {\n    const stream = parser.lexer.stream;\n    const tableState = this.tableState;\n    stream.pos = tableState.streamPos;\n    parser.buf1 = tableState.parserBuf1;\n    parser.buf2 = tableState.parserBuf2;\n    let obj;\n    while (true) {\n      if (!(\"firstEntryNum\" in tableState) || !(\"entryCount\" in tableState)) {\n        if (isCmd(obj = parser.getObj(), \"trailer\")) {\n          break;\n        }\n        tableState.firstEntryNum = obj;\n        tableState.entryCount = parser.getObj();\n      }\n      let first = tableState.firstEntryNum;\n      const count = tableState.entryCount;\n      if (!Number.isInteger(first) || !Number.isInteger(count)) {\n        throw new FormatError(\"Invalid XRef table: wrong types in subsection header\");\n      }\n      for (let i = tableState.entryNum; i < count; i++) {\n        tableState.streamPos = stream.pos;\n        tableState.entryNum = i;\n        tableState.parserBuf1 = parser.buf1;\n        tableState.parserBuf2 = parser.buf2;\n        const entry = {};\n        entry.offset = parser.getObj();\n        entry.gen = parser.getObj();\n        const type = parser.getObj();\n        if (type instanceof Cmd) {\n          switch (type.cmd) {\n            case \"f\":\n              entry.free = true;\n              break;\n            case \"n\":\n              entry.uncompressed = true;\n              break;\n          }\n        }\n        if (!Number.isInteger(entry.offset) || !Number.isInteger(entry.gen) || !(entry.free || entry.uncompressed)) {\n          throw new FormatError(`Invalid entry in XRef subsection: ${first}, ${count}`);\n        }\n        if (i === 0 && entry.free && first === 1) {\n          first = 0;\n        }\n        if (!this.entries[i + first]) {\n          this.entries[i + first] = entry;\n        }\n      }\n      tableState.entryNum = 0;\n      tableState.streamPos = stream.pos;\n      tableState.parserBuf1 = parser.buf1;\n      tableState.parserBuf2 = parser.buf2;\n      delete tableState.firstEntryNum;\n      delete tableState.entryCount;\n    }\n    if (this.entries[0] && !this.entries[0].free) {\n      throw new FormatError(\"Invalid XRef table: unexpected first object\");\n    }\n    return obj;\n  }\n  processXRefStream(stream) {\n    if (!(\"streamState\" in this)) {\n      const streamParameters = stream.dict;\n      const byteWidths = streamParameters.get(\"W\");\n      let range = streamParameters.get(\"Index\");\n      if (!range) {\n        range = [0, streamParameters.get(\"Size\")];\n      }\n      this.streamState = {\n        entryRanges: range,\n        byteWidths,\n        entryNum: 0,\n        streamPos: stream.pos\n      };\n    }\n    this.readXRefStream(stream);\n    delete this.streamState;\n    return stream.dict;\n  }\n  readXRefStream(stream) {\n    const streamState = this.streamState;\n    stream.pos = streamState.streamPos;\n    const [typeFieldWidth, offsetFieldWidth, generationFieldWidth] = streamState.byteWidths;\n    const entryRanges = streamState.entryRanges;\n    while (entryRanges.length > 0) {\n      const [first, n] = entryRanges;\n      if (!Number.isInteger(first) || !Number.isInteger(n)) {\n        throw new FormatError(`Invalid XRef range fields: ${first}, ${n}`);\n      }\n      if (!Number.isInteger(typeFieldWidth) || !Number.isInteger(offsetFieldWidth) || !Number.isInteger(generationFieldWidth)) {\n        throw new FormatError(`Invalid XRef entry fields length: ${first}, ${n}`);\n      }\n      for (let i = streamState.entryNum; i < n; ++i) {\n        streamState.entryNum = i;\n        streamState.streamPos = stream.pos;\n        let type = 0,\n          offset = 0,\n          generation = 0;\n        for (let j = 0; j < typeFieldWidth; ++j) {\n          const typeByte = stream.getByte();\n          if (typeByte === -1) {\n            throw new FormatError(\"Invalid XRef byteWidths 'type'.\");\n          }\n          type = type << 8 | typeByte;\n        }\n        if (typeFieldWidth === 0) {\n          type = 1;\n        }\n        for (let j = 0; j < offsetFieldWidth; ++j) {\n          const offsetByte = stream.getByte();\n          if (offsetByte === -1) {\n            throw new FormatError(\"Invalid XRef byteWidths 'offset'.\");\n          }\n          offset = offset << 8 | offsetByte;\n        }\n        for (let j = 0; j < generationFieldWidth; ++j) {\n          const generationByte = stream.getByte();\n          if (generationByte === -1) {\n            throw new FormatError(\"Invalid XRef byteWidths 'generation'.\");\n          }\n          generation = generation << 8 | generationByte;\n        }\n        const entry = {};\n        entry.offset = offset;\n        entry.gen = generation;\n        switch (type) {\n          case 0:\n            entry.free = true;\n            break;\n          case 1:\n            entry.uncompressed = true;\n            break;\n          case 2:\n            break;\n          default:\n            throw new FormatError(`Invalid XRef entry type: ${type}`);\n        }\n        if (!this.entries[first + i]) {\n          this.entries[first + i] = entry;\n        }\n      }\n      streamState.entryNum = 0;\n      streamState.streamPos = stream.pos;\n      entryRanges.splice(0, 2);\n    }\n  }\n  indexObjects() {\n    const TAB = 0x9,\n      LF = 0xa,\n      CR = 0xd,\n      SPACE = 0x20;\n    const PERCENT = 0x25,\n      LT = 0x3c;\n    function readToken(data, offset) {\n      let token = \"\",\n        ch = data[offset];\n      while (ch !== LF && ch !== CR && ch !== LT) {\n        if (++offset >= data.length) {\n          break;\n        }\n        token += String.fromCharCode(ch);\n        ch = data[offset];\n      }\n      return token;\n    }\n    function skipUntil(data, offset, what) {\n      const length = what.length,\n        dataLength = data.length;\n      let skipped = 0;\n      while (offset < dataLength) {\n        let i = 0;\n        while (i < length && data[offset + i] === what[i]) {\n          ++i;\n        }\n        if (i >= length) {\n          break;\n        }\n        offset++;\n        skipped++;\n      }\n      return skipped;\n    }\n    const gEndobjRegExp = /\\b(endobj|\\d+\\s+\\d+\\s+obj|xref|trailer\\s*<<)\\b/g;\n    const gStartxrefRegExp = /\\b(startxref|\\d+\\s+\\d+\\s+obj)\\b/g;\n    const objRegExp = /^(\\d+)\\s+(\\d+)\\s+obj\\b/;\n    const trailerBytes = new Uint8Array([116, 114, 97, 105, 108, 101, 114]);\n    const startxrefBytes = new Uint8Array([115, 116, 97, 114, 116, 120, 114, 101, 102]);\n    const xrefBytes = new Uint8Array([47, 88, 82, 101, 102]);\n    this.entries.length = 0;\n    this._cacheMap.clear();\n    const stream = this.stream;\n    stream.pos = 0;\n    const buffer = stream.getBytes(),\n      bufferStr = bytesToString(buffer),\n      length = buffer.length;\n    let position = stream.start;\n    const trailers = [],\n      xrefStms = [];\n    while (position < length) {\n      let ch = buffer[position];\n      if (ch === TAB || ch === LF || ch === CR || ch === SPACE) {\n        ++position;\n        continue;\n      }\n      if (ch === PERCENT) {\n        do {\n          ++position;\n          if (position >= length) {\n            break;\n          }\n          ch = buffer[position];\n        } while (ch !== LF && ch !== CR);\n        continue;\n      }\n      const token = readToken(buffer, position);\n      let m;\n      if (token.startsWith(\"xref\") && (token.length === 4 || /\\s/.test(token[4]))) {\n        position += skipUntil(buffer, position, trailerBytes);\n        trailers.push(position);\n        position += skipUntil(buffer, position, startxrefBytes);\n      } else if (m = objRegExp.exec(token)) {\n        const num = m[1] | 0,\n          gen = m[2] | 0;\n        const startPos = position + token.length;\n        let contentLength,\n          updateEntries = false;\n        if (!this.entries[num]) {\n          updateEntries = true;\n        } else if (this.entries[num].gen === gen) {\n          try {\n            const parser = new Parser({\n              lexer: new Lexer(stream.makeSubStream(startPos))\n            });\n            parser.getObj();\n            updateEntries = true;\n          } catch (ex) {\n            if (ex instanceof ParserEOFException) {\n              warn(`indexObjects -- checking object (${token}): \"${ex}\".`);\n            } else {\n              updateEntries = true;\n            }\n          }\n        }\n        if (updateEntries) {\n          this.entries[num] = {\n            offset: position - stream.start,\n            gen,\n            uncompressed: true\n          };\n        }\n        gEndobjRegExp.lastIndex = startPos;\n        const match = gEndobjRegExp.exec(bufferStr);\n        if (match) {\n          const endPos = gEndobjRegExp.lastIndex + 1;\n          contentLength = endPos - position;\n          if (match[1] !== \"endobj\") {\n            warn(`indexObjects: Found \"${match[1]}\" inside of another \"obj\", ` + 'caused by missing \"endobj\" -- trying to recover.');\n            contentLength -= match[1].length + 1;\n          }\n        } else {\n          contentLength = length - position;\n        }\n        const content = buffer.subarray(position, position + contentLength);\n        const xrefTagOffset = skipUntil(content, 0, xrefBytes);\n        if (xrefTagOffset < contentLength && content[xrefTagOffset + 5] < 64) {\n          xrefStms.push(position - stream.start);\n          this._xrefStms.add(position - stream.start);\n        }\n        position += contentLength;\n      } else if (token.startsWith(\"trailer\") && (token.length === 7 || /\\s/.test(token[7]))) {\n        trailers.push(position);\n        const startPos = position + token.length;\n        let contentLength;\n        gStartxrefRegExp.lastIndex = startPos;\n        const match = gStartxrefRegExp.exec(bufferStr);\n        if (match) {\n          const endPos = gStartxrefRegExp.lastIndex + 1;\n          contentLength = endPos - position;\n          if (match[1] !== \"startxref\") {\n            warn(`indexObjects: Found \"${match[1]}\" after \"trailer\", ` + 'caused by missing \"startxref\" -- trying to recover.');\n            contentLength -= match[1].length + 1;\n          }\n        } else {\n          contentLength = length - position;\n        }\n        position += contentLength;\n      } else {\n        position += token.length + 1;\n      }\n    }\n    for (const xrefStm of xrefStms) {\n      this.startXRefQueue.push(xrefStm);\n      this.readXRef(true);\n    }\n    const trailerDicts = [];\n    let isEncrypted = false;\n    for (const trailer of trailers) {\n      stream.pos = trailer;\n      const parser = new Parser({\n        lexer: new Lexer(stream),\n        xref: this,\n        allowStreams: true,\n        recoveryMode: true\n      });\n      const obj = parser.getObj();\n      if (!isCmd(obj, \"trailer\")) {\n        continue;\n      }\n      const dict = parser.getObj();\n      if (!(dict instanceof Dict)) {\n        continue;\n      }\n      trailerDicts.push(dict);\n      if (dict.has(\"Encrypt\")) {\n        isEncrypted = true;\n      }\n    }\n    let trailerDict, trailerError;\n    for (const dict of [...trailerDicts, \"genFallback\", ...trailerDicts]) {\n      if (dict === \"genFallback\") {\n        if (!trailerError) {\n          break;\n        }\n        this._generationFallback = true;\n        continue;\n      }\n      let validPagesDict = false;\n      try {\n        const rootDict = dict.get(\"Root\");\n        if (!(rootDict instanceof Dict)) {\n          continue;\n        }\n        const pagesDict = rootDict.get(\"Pages\");\n        if (!(pagesDict instanceof Dict)) {\n          continue;\n        }\n        const pagesCount = pagesDict.get(\"Count\");\n        if (Number.isInteger(pagesCount)) {\n          validPagesDict = true;\n        }\n      } catch (ex) {\n        trailerError = ex;\n        continue;\n      }\n      if (validPagesDict && (!isEncrypted || dict.has(\"Encrypt\")) && dict.has(\"ID\")) {\n        return dict;\n      }\n      trailerDict = dict;\n    }\n    if (trailerDict) {\n      return trailerDict;\n    }\n    if (this.topDict) {\n      return this.topDict;\n    }\n    throw new InvalidPDFException(\"Invalid PDF structure.\");\n  }\n  readXRef(recoveryMode = false) {\n    const stream = this.stream;\n    const startXRefParsedCache = new Set();\n    while (this.startXRefQueue.length) {\n      try {\n        const startXRef = this.startXRefQueue[0];\n        if (startXRefParsedCache.has(startXRef)) {\n          warn(\"readXRef - skipping XRef table since it was already parsed.\");\n          this.startXRefQueue.shift();\n          continue;\n        }\n        startXRefParsedCache.add(startXRef);\n        stream.pos = startXRef + stream.start;\n        const parser = new Parser({\n          lexer: new Lexer(stream),\n          xref: this,\n          allowStreams: true\n        });\n        let obj = parser.getObj();\n        let dict;\n        if (isCmd(obj, \"xref\")) {\n          dict = this.processXRefTable(parser);\n          if (!this.topDict) {\n            this.topDict = dict;\n          }\n          obj = dict.get(\"XRefStm\");\n          if (Number.isInteger(obj) && !this._xrefStms.has(obj)) {\n            this._xrefStms.add(obj);\n            this.startXRefQueue.push(obj);\n            this.#firstXRefStmPos ??= obj;\n          }\n        } else if (Number.isInteger(obj)) {\n          if (!Number.isInteger(parser.getObj()) || !isCmd(parser.getObj(), \"obj\") || !((obj = parser.getObj()) instanceof BaseStream)) {\n            throw new FormatError(\"Invalid XRef stream\");\n          }\n          dict = this.processXRefStream(obj);\n          if (!this.topDict) {\n            this.topDict = dict;\n          }\n          if (!dict) {\n            throw new FormatError(\"Failed to read XRef stream\");\n          }\n        } else {\n          throw new FormatError(\"Invalid XRef stream header\");\n        }\n        obj = dict.get(\"Prev\");\n        if (Number.isInteger(obj)) {\n          this.startXRefQueue.push(obj);\n        } else if (obj instanceof Ref) {\n          this.startXRefQueue.push(obj.num);\n        }\n      } catch (e) {\n        if (e instanceof MissingDataException) {\n          throw e;\n        }\n        info(\"(while reading XRef): \" + e);\n      }\n      this.startXRefQueue.shift();\n    }\n    if (this.topDict) {\n      return this.topDict;\n    }\n    if (recoveryMode) {\n      return undefined;\n    }\n    throw new XRefParseException();\n  }\n  get lastXRefStreamPos() {\n    return this.#firstXRefStmPos ?? (this._xrefStms.size > 0 ? Math.max(...this._xrefStms) : null);\n  }\n  getEntry(i) {\n    const xrefEntry = this.entries[i];\n    if (xrefEntry && !xrefEntry.free && xrefEntry.offset) {\n      return xrefEntry;\n    }\n    return null;\n  }\n  fetchIfRef(obj, suppressEncryption = false) {\n    if (obj instanceof Ref) {\n      return this.fetch(obj, suppressEncryption);\n    }\n    return obj;\n  }\n  fetch(ref, suppressEncryption = false) {\n    if (!(ref instanceof Ref)) {\n      throw new Error(\"ref object is not a reference\");\n    }\n    const num = ref.num;\n    const cacheEntry = this._cacheMap.get(num);\n    if (cacheEntry !== undefined) {\n      if (cacheEntry instanceof Dict && !cacheEntry.objId) {\n        cacheEntry.objId = ref.toString();\n      }\n      return cacheEntry;\n    }\n    let xrefEntry = this.getEntry(num);\n    if (xrefEntry === null) {\n      this._cacheMap.set(num, xrefEntry);\n      return xrefEntry;\n    }\n    if (this._pendingRefs.has(ref)) {\n      this._pendingRefs.remove(ref);\n      warn(`Ignoring circular reference: ${ref}.`);\n      return CIRCULAR_REF;\n    }\n    this._pendingRefs.put(ref);\n    try {\n      xrefEntry = xrefEntry.uncompressed ? this.fetchUncompressed(ref, xrefEntry, suppressEncryption) : this.fetchCompressed(ref, xrefEntry, suppressEncryption);\n      this._pendingRefs.remove(ref);\n    } catch (ex) {\n      this._pendingRefs.remove(ref);\n      throw ex;\n    }\n    if (xrefEntry instanceof Dict) {\n      xrefEntry.objId = ref.toString();\n    } else if (xrefEntry instanceof BaseStream) {\n      xrefEntry.dict.objId = ref.toString();\n    }\n    return xrefEntry;\n  }\n  fetchUncompressed(ref, xrefEntry, suppressEncryption = false) {\n    const gen = ref.gen;\n    let num = ref.num;\n    if (xrefEntry.gen !== gen) {\n      const msg = `Inconsistent generation in XRef: ${ref}`;\n      if (this._generationFallback && xrefEntry.gen < gen) {\n        warn(msg);\n        return this.fetchUncompressed(Ref.get(num, xrefEntry.gen), xrefEntry, suppressEncryption);\n      }\n      throw new XRefEntryException(msg);\n    }\n    const stream = this.stream.makeSubStream(xrefEntry.offset + this.stream.start);\n    const parser = new Parser({\n      lexer: new Lexer(stream),\n      xref: this,\n      allowStreams: true\n    });\n    const obj1 = parser.getObj();\n    const obj2 = parser.getObj();\n    const obj3 = parser.getObj();\n    if (obj1 !== num || obj2 !== gen || !(obj3 instanceof Cmd)) {\n      throw new XRefEntryException(`Bad (uncompressed) XRef entry: ${ref}`);\n    }\n    if (obj3.cmd !== \"obj\") {\n      if (obj3.cmd.startsWith(\"obj\")) {\n        num = parseInt(obj3.cmd.substring(3), 10);\n        if (!Number.isNaN(num)) {\n          return num;\n        }\n      }\n      throw new XRefEntryException(`Bad (uncompressed) XRef entry: ${ref}`);\n    }\n    xrefEntry = this.encrypt && !suppressEncryption ? parser.getObj(this.encrypt.createCipherTransform(num, gen)) : parser.getObj();\n    if (!(xrefEntry instanceof BaseStream)) {\n      this._cacheMap.set(num, xrefEntry);\n    }\n    return xrefEntry;\n  }\n  fetchCompressed(ref, xrefEntry, suppressEncryption = false) {\n    const tableOffset = xrefEntry.offset;\n    const stream = this.fetch(Ref.get(tableOffset, 0));\n    if (!(stream instanceof BaseStream)) {\n      throw new FormatError(\"bad ObjStm stream\");\n    }\n    const first = stream.dict.get(\"First\");\n    const n = stream.dict.get(\"N\");\n    if (!Number.isInteger(first) || !Number.isInteger(n)) {\n      throw new FormatError(\"invalid first and n parameters for ObjStm stream\");\n    }\n    let parser = new Parser({\n      lexer: new Lexer(stream),\n      xref: this,\n      allowStreams: true\n    });\n    const nums = new Array(n);\n    const offsets = new Array(n);\n    for (let i = 0; i < n; ++i) {\n      const num = parser.getObj();\n      if (!Number.isInteger(num)) {\n        throw new FormatError(`invalid object number in the ObjStm stream: ${num}`);\n      }\n      const offset = parser.getObj();\n      if (!Number.isInteger(offset)) {\n        throw new FormatError(`invalid object offset in the ObjStm stream: ${offset}`);\n      }\n      nums[i] = num;\n      offsets[i] = offset;\n    }\n    const start = (stream.start || 0) + first;\n    const entries = new Array(n);\n    for (let i = 0; i < n; ++i) {\n      const length = i < n - 1 ? offsets[i + 1] - offsets[i] : undefined;\n      if (length < 0) {\n        throw new FormatError(\"Invalid offset in the ObjStm stream.\");\n      }\n      parser = new Parser({\n        lexer: new Lexer(stream.makeSubStream(start + offsets[i], length, stream.dict)),\n        xref: this,\n        allowStreams: true\n      });\n      const obj = parser.getObj();\n      entries[i] = obj;\n      if (obj instanceof BaseStream) {\n        continue;\n      }\n      const num = nums[i],\n        entry = this.entries[num];\n      if (entry && entry.offset === tableOffset && entry.gen === i) {\n        this._cacheMap.set(num, obj);\n      }\n    }\n    xrefEntry = entries[xrefEntry.gen];\n    if (xrefEntry === undefined) {\n      throw new XRefEntryException(`Bad (compressed) XRef entry: ${ref}`);\n    }\n    return xrefEntry;\n  }\n  async fetchIfRefAsync(obj, suppressEncryption) {\n    if (obj instanceof Ref) {\n      return this.fetchAsync(obj, suppressEncryption);\n    }\n    return obj;\n  }\n  async fetchAsync(ref, suppressEncryption) {\n    try {\n      return this.fetch(ref, suppressEncryption);\n    } catch (ex) {\n      if (!(ex instanceof MissingDataException)) {\n        throw ex;\n      }\n      await this.pdfManager.requestRange(ex.begin, ex.end);\n      return this.fetchAsync(ref, suppressEncryption);\n    }\n  }\n  getCatalogObj() {\n    return this.root;\n  }\n}\n\n;// ./src/core/document.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst DEFAULT_USER_UNIT = 1.0;\nconst LETTER_SIZE_MEDIABOX = [0, 0, 612, 792];\nclass Page {\n  constructor({\n    pdfManager,\n    xref,\n    pageIndex,\n    pageDict,\n    ref,\n    globalIdFactory,\n    fontCache,\n    builtInCMapCache,\n    standardFontDataCache,\n    globalImageCache,\n    systemFontCache,\n    nonBlendModesSet,\n    xfaFactory\n  }) {\n    this.pdfManager = pdfManager;\n    this.pageIndex = pageIndex;\n    this.pageDict = pageDict;\n    this.xref = xref;\n    this.ref = ref;\n    this.fontCache = fontCache;\n    this.builtInCMapCache = builtInCMapCache;\n    this.standardFontDataCache = standardFontDataCache;\n    this.globalImageCache = globalImageCache;\n    this.systemFontCache = systemFontCache;\n    this.nonBlendModesSet = nonBlendModesSet;\n    this.evaluatorOptions = pdfManager.evaluatorOptions;\n    this.resourcesPromise = null;\n    this.xfaFactory = xfaFactory;\n    const idCounters = {\n      obj: 0\n    };\n    this._localIdFactory = class extends globalIdFactory {\n      static createObjId() {\n        return `p${pageIndex}_${++idCounters.obj}`;\n      }\n      static getPageObjId() {\n        return `p${ref.toString()}`;\n      }\n    };\n  }\n  _getInheritableProperty(key, getArray = false) {\n    const value = getInheritableProperty({\n      dict: this.pageDict,\n      key,\n      getArray,\n      stopWhenFound: false\n    });\n    if (!Array.isArray(value)) {\n      return value;\n    }\n    if (value.length === 1 || !(value[0] instanceof Dict)) {\n      return value[0];\n    }\n    return Dict.merge({\n      xref: this.xref,\n      dictArray: value\n    });\n  }\n  get content() {\n    return this.pageDict.getArray(\"Contents\");\n  }\n  get resources() {\n    const resources = this._getInheritableProperty(\"Resources\");\n    return shadow(this, \"resources\", resources instanceof Dict ? resources : Dict.empty);\n  }\n  _getBoundingBox(name) {\n    if (this.xfaData) {\n      return this.xfaData.bbox;\n    }\n    let box = this._getInheritableProperty(name, true);\n    if (Array.isArray(box) && box.length === 4) {\n      box = Util.normalizeRect(box);\n      if (box[2] - box[0] > 0 && box[3] - box[1] > 0) {\n        return box;\n      }\n      warn(`Empty, or invalid, /${name} entry.`);\n    }\n    return null;\n  }\n  get mediaBox() {\n    return shadow(this, \"mediaBox\", this._getBoundingBox(\"MediaBox\") || LETTER_SIZE_MEDIABOX);\n  }\n  get cropBox() {\n    return shadow(this, \"cropBox\", this._getBoundingBox(\"CropBox\") || this.mediaBox);\n  }\n  get userUnit() {\n    let obj = this.pageDict.get(\"UserUnit\");\n    if (typeof obj !== \"number\" || obj <= 0) {\n      obj = DEFAULT_USER_UNIT;\n    }\n    return shadow(this, \"userUnit\", obj);\n  }\n  get view() {\n    const {\n      cropBox,\n      mediaBox\n    } = this;\n    if (cropBox !== mediaBox && !isArrayEqual(cropBox, mediaBox)) {\n      const box = Util.intersect(cropBox, mediaBox);\n      if (box && box[2] - box[0] > 0 && box[3] - box[1] > 0) {\n        return shadow(this, \"view\", box);\n      }\n      warn(\"Empty /CropBox and /MediaBox intersection.\");\n    }\n    return shadow(this, \"view\", mediaBox);\n  }\n  get rotate() {\n    let rotate = this._getInheritableProperty(\"Rotate\") || 0;\n    if (rotate % 90 !== 0) {\n      rotate = 0;\n    } else if (rotate >= 360) {\n      rotate %= 360;\n    } else if (rotate < 0) {\n      rotate = (rotate % 360 + 360) % 360;\n    }\n    return shadow(this, \"rotate\", rotate);\n  }\n  _onSubStreamError(reason, objId) {\n    if (this.evaluatorOptions.ignoreErrors) {\n      warn(`getContentStream - ignoring sub-stream (${objId}): \"${reason}\".`);\n      return;\n    }\n    throw reason;\n  }\n  getContentStream() {\n    return this.pdfManager.ensure(this, \"content\").then(content => {\n      if (content instanceof BaseStream) {\n        return content;\n      }\n      if (Array.isArray(content)) {\n        return new StreamsSequenceStream(content, this._onSubStreamError.bind(this));\n      }\n      return new NullStream();\n    });\n  }\n  get xfaData() {\n    return shadow(this, \"xfaData\", this.xfaFactory ? {\n      bbox: this.xfaFactory.getBoundingBox(this.pageIndex)\n    } : null);\n  }\n  #replaceIdByRef(annotations, deletedAnnotations, existingAnnotations) {\n    for (const annotation of annotations) {\n      if (annotation.id) {\n        const ref = Ref.fromString(annotation.id);\n        if (!ref) {\n          warn(`A non-linked annotation cannot be modified: ${annotation.id}`);\n          continue;\n        }\n        if (annotation.deleted) {\n          deletedAnnotations.put(ref);\n          continue;\n        }\n        existingAnnotations?.put(ref);\n        annotation.ref = ref;\n        delete annotation.id;\n      }\n    }\n  }\n  async saveNewAnnotations(handler, task, annotations, imagePromises) {\n    if (this.xfaFactory) {\n      throw new Error(\"XFA: Cannot save new annotations.\");\n    }\n    const partialEvaluator = new PartialEvaluator({\n      xref: this.xref,\n      handler,\n      pageIndex: this.pageIndex,\n      idFactory: this._localIdFactory,\n      fontCache: this.fontCache,\n      builtInCMapCache: this.builtInCMapCache,\n      standardFontDataCache: this.standardFontDataCache,\n      globalImageCache: this.globalImageCache,\n      systemFontCache: this.systemFontCache,\n      options: this.evaluatorOptions\n    });\n    const deletedAnnotations = new RefSet();\n    const existingAnnotations = new RefSet();\n    this.#replaceIdByRef(annotations, deletedAnnotations, existingAnnotations);\n    const pageDict = this.pageDict;\n    const annotationsArray = this.annotations.filter(a => !(a instanceof Ref && deletedAnnotations.has(a)));\n    const newData = await AnnotationFactory.saveNewAnnotations(partialEvaluator, task, annotations, imagePromises);\n    for (const {\n      ref\n    } of newData.annotations) {\n      if (ref instanceof Ref && !existingAnnotations.has(ref)) {\n        annotationsArray.push(ref);\n      }\n    }\n    const savedDict = pageDict.get(\"Annots\");\n    pageDict.set(\"Annots\", annotationsArray);\n    const buffer = [];\n    await writeObject(this.ref, pageDict, buffer, this.xref);\n    if (savedDict) {\n      pageDict.set(\"Annots\", savedDict);\n    }\n    const objects = newData.dependencies;\n    objects.push({\n      ref: this.ref,\n      data: buffer.join(\"\")\n    }, ...newData.annotations);\n    return objects;\n  }\n  save(handler, task, annotationStorage) {\n    const partialEvaluator = new PartialEvaluator({\n      xref: this.xref,\n      handler,\n      pageIndex: this.pageIndex,\n      idFactory: this._localIdFactory,\n      fontCache: this.fontCache,\n      builtInCMapCache: this.builtInCMapCache,\n      standardFontDataCache: this.standardFontDataCache,\n      globalImageCache: this.globalImageCache,\n      systemFontCache: this.systemFontCache,\n      options: this.evaluatorOptions\n    });\n    return this._parsedAnnotations.then(function (annotations) {\n      const newRefsPromises = [];\n      for (const annotation of annotations) {\n        if (!annotation.mustBePrinted(annotationStorage)) {\n          continue;\n        }\n        newRefsPromises.push(annotation.save(partialEvaluator, task, annotationStorage).catch(function (reason) {\n          warn(\"save - ignoring annotation data during \" + `\"${task.name}\" task: \"${reason}\".`);\n          return null;\n        }));\n      }\n      return Promise.all(newRefsPromises).then(function (newRefs) {\n        return newRefs.filter(newRef => !!newRef);\n      });\n    });\n  }\n  loadResources(keys) {\n    if (!this.resourcesPromise) {\n      this.resourcesPromise = this.pdfManager.ensure(this, \"resources\");\n    }\n    return this.resourcesPromise.then(() => {\n      const objectLoader = new ObjectLoader(this.resources, keys, this.xref);\n      return objectLoader.load();\n    });\n  }\n  getOperatorList({\n    handler,\n    sink,\n    task,\n    intent,\n    cacheKey,\n    imageOutLlamaParse = \"./\",\n    disableImageExtraction = false,\n    annotationStorage = null\n  }) {\n    const contentStreamPromise = this.getContentStream();\n    const resourcesPromise = this.loadResources([\"ColorSpace\", \"ExtGState\", \"Font\", \"Pattern\", \"Properties\", \"Shading\", \"XObject\"]);\n    const partialEvaluator = new PartialEvaluator({\n      xref: this.xref,\n      handler,\n      pageIndex: this.pageIndex,\n      idFactory: this._localIdFactory,\n      fontCache: this.fontCache,\n      builtInCMapCache: this.builtInCMapCache,\n      standardFontDataCache: this.standardFontDataCache,\n      globalImageCache: this.globalImageCache,\n      systemFontCache: this.systemFontCache,\n      options: this.evaluatorOptions,\n      imageOutLlamaParse: imageOutLlamaParse,\n      disableImageExtraction: disableImageExtraction\n    });\n    const newAnnotationsByPage = !this.xfaFactory ? getNewAnnotationsMap(annotationStorage) : null;\n    let deletedAnnotations = null;\n    let newAnnotationsPromise = Promise.resolve(null);\n    if (newAnnotationsByPage) {\n      const newAnnotations = newAnnotationsByPage.get(this.pageIndex);\n      if (newAnnotations) {\n        const annotationGlobalsPromise = this.pdfManager.ensureDoc(\"annotationGlobals\");\n        let imagePromises;\n        const missingBitmaps = new Set();\n        for (const {\n          bitmapId,\n          bitmap\n        } of newAnnotations) {\n          if (bitmapId && !bitmap && !missingBitmaps.has(bitmapId)) {\n            missingBitmaps.add(bitmapId);\n          }\n        }\n        const {\n          isOffscreenCanvasSupported\n        } = this.evaluatorOptions;\n        if (missingBitmaps.size > 0) {\n          const annotationWithBitmaps = newAnnotations.slice();\n          for (const [key, annotation] of annotationStorage) {\n            if (!key.startsWith(AnnotationEditorPrefix)) {\n              continue;\n            }\n            if (annotation.bitmap && missingBitmaps.has(annotation.bitmapId)) {\n              annotationWithBitmaps.push(annotation);\n            }\n          }\n          imagePromises = AnnotationFactory.generateImages(annotationWithBitmaps, this.xref, isOffscreenCanvasSupported);\n        } else {\n          imagePromises = AnnotationFactory.generateImages(newAnnotations, this.xref, isOffscreenCanvasSupported);\n        }\n        deletedAnnotations = new RefSet();\n        this.#replaceIdByRef(newAnnotations, deletedAnnotations, null);\n        newAnnotationsPromise = annotationGlobalsPromise.then(annotationGlobals => {\n          if (!annotationGlobals) {\n            return null;\n          }\n          return AnnotationFactory.printNewAnnotations(annotationGlobals, partialEvaluator, task, newAnnotations, imagePromises);\n        });\n      }\n    }\n    const dataPromises = Promise.all([contentStreamPromise, resourcesPromise]);\n    const pageListPromise = dataPromises.then(([contentStream]) => {\n      const opList = new OperatorList(intent, sink);\n      handler.send(\"StartRenderPage\", {\n        transparency: partialEvaluator.hasBlendModes(this.resources, this.nonBlendModesSet),\n        pageIndex: this.pageIndex,\n        cacheKey\n      });\n      return partialEvaluator.getOperatorList({\n        stream: contentStream,\n        task,\n        resources: this.resources,\n        operatorList: opList\n      }).then(function () {\n        return opList;\n      });\n    });\n    return Promise.all([pageListPromise, this._parsedAnnotations, newAnnotationsPromise]).then(function ([pageOpList, annotations, newAnnotations]) {\n      if (newAnnotations) {\n        annotations = annotations.filter(a => !(a.ref && deletedAnnotations.has(a.ref)));\n        for (let i = 0, ii = newAnnotations.length; i < ii; i++) {\n          const newAnnotation = newAnnotations[i];\n          if (newAnnotation.refToReplace) {\n            const j = annotations.findIndex(a => a.ref && isRefsEqual(a.ref, newAnnotation.refToReplace));\n            if (j >= 0) {\n              annotations.splice(j, 1, newAnnotation);\n              newAnnotations.splice(i--, 1);\n              ii--;\n            }\n          }\n        }\n        annotations = annotations.concat(newAnnotations);\n      }\n      if (annotations.length === 0 || intent & RenderingIntentFlag.ANNOTATIONS_DISABLE) {\n        pageOpList.flush(true);\n        return {\n          length: pageOpList.totalLength\n        };\n      }\n      const renderForms = !!(intent & RenderingIntentFlag.ANNOTATIONS_FORMS),\n        intentAny = !!(intent & RenderingIntentFlag.ANY),\n        intentDisplay = !!(intent & RenderingIntentFlag.DISPLAY),\n        intentPrint = !!(intent & RenderingIntentFlag.PRINT);\n      const opListPromises = [];\n      for (const annotation of annotations) {\n        if (intentAny || intentDisplay && annotation.mustBeViewed(annotationStorage, renderForms) || intentPrint && annotation.mustBePrinted(annotationStorage)) {\n          opListPromises.push(annotation.getOperatorList(partialEvaluator, task, intent, renderForms, annotationStorage).catch(function (reason) {\n            warn(\"getOperatorList - ignoring annotation data during \" + `\"${task.name}\" task: \"${reason}\".`);\n            return {\n              opList: null,\n              separateForm: false,\n              separateCanvas: false\n            };\n          }));\n        }\n      }\n      return Promise.all(opListPromises).then(function (opLists) {\n        let form = false,\n          canvas = false;\n        for (const {\n          opList,\n          separateForm,\n          separateCanvas\n        } of opLists) {\n          pageOpList.addOpList(opList);\n          form ||= separateForm;\n          canvas ||= separateCanvas;\n        }\n        pageOpList.flush(true, {\n          form,\n          canvas\n        });\n        return {\n          length: pageOpList.totalLength\n        };\n      });\n    });\n  }\n  extractTextContent({\n    handler,\n    task,\n    includeMarkedContent,\n    disableNormalization,\n    sink\n  }) {\n    const contentStreamPromise = this.getContentStream();\n    const resourcesPromise = this.loadResources([\"ExtGState\", \"Font\", \"Properties\", \"XObject\"]);\n    const dataPromises = Promise.all([contentStreamPromise, resourcesPromise]);\n    return dataPromises.then(([contentStream]) => {\n      const partialEvaluator = new PartialEvaluator({\n        xref: this.xref,\n        handler,\n        pageIndex: this.pageIndex,\n        idFactory: this._localIdFactory,\n        fontCache: this.fontCache,\n        builtInCMapCache: this.builtInCMapCache,\n        standardFontDataCache: this.standardFontDataCache,\n        globalImageCache: this.globalImageCache,\n        systemFontCache: this.systemFontCache,\n        options: this.evaluatorOptions\n      });\n      return partialEvaluator.getTextContent({\n        stream: contentStream,\n        task,\n        resources: this.resources,\n        includeMarkedContent,\n        disableNormalization,\n        sink,\n        viewBox: this.view\n      });\n    });\n  }\n  async getStructTree() {\n    const structTreeRoot = await this.pdfManager.ensureCatalog(\"structTreeRoot\");\n    if (!structTreeRoot) {\n      return null;\n    }\n    await this._parsedAnnotations;\n    const structTree = await this.pdfManager.ensure(this, \"_parseStructTree\", [structTreeRoot]);\n    return structTree.serializable;\n  }\n  _parseStructTree(structTreeRoot) {\n    const tree = new StructTreePage(structTreeRoot, this.pageDict);\n    tree.parse(this.ref);\n    return tree;\n  }\n  async getAnnotationsData(handler, task, intent) {\n    const annotations = await this._parsedAnnotations;\n    if (annotations.length === 0) {\n      return annotations;\n    }\n    const annotationsData = [],\n      textContentPromises = [];\n    let partialEvaluator;\n    const intentAny = !!(intent & RenderingIntentFlag.ANY),\n      intentDisplay = !!(intent & RenderingIntentFlag.DISPLAY),\n      intentPrint = !!(intent & RenderingIntentFlag.PRINT);\n    for (const annotation of annotations) {\n      const isVisible = intentAny || intentDisplay && annotation.viewable;\n      if (isVisible || intentPrint && annotation.printable) {\n        annotationsData.push(annotation.data);\n      }\n      if (annotation.hasTextContent && isVisible) {\n        partialEvaluator ||= new PartialEvaluator({\n          xref: this.xref,\n          handler,\n          pageIndex: this.pageIndex,\n          idFactory: this._localIdFactory,\n          fontCache: this.fontCache,\n          builtInCMapCache: this.builtInCMapCache,\n          standardFontDataCache: this.standardFontDataCache,\n          globalImageCache: this.globalImageCache,\n          systemFontCache: this.systemFontCache,\n          options: this.evaluatorOptions\n        });\n        textContentPromises.push(annotation.extractTextContent(partialEvaluator, task, [-Infinity, -Infinity, Infinity, Infinity]).catch(function (reason) {\n          warn(`getAnnotationsData - ignoring textContent during \"${task.name}\" task: \"${reason}\".`);\n        }));\n      }\n    }\n    await Promise.all(textContentPromises);\n    return annotationsData;\n  }\n  get annotations() {\n    const annots = this._getInheritableProperty(\"Annots\");\n    return shadow(this, \"annotations\", Array.isArray(annots) ? annots : []);\n  }\n  get _parsedAnnotations() {\n    const promise = this.pdfManager.ensure(this, \"annotations\").then(async annots => {\n      if (annots.length === 0) {\n        return annots;\n      }\n      const annotationGlobals = await this.pdfManager.ensureDoc(\"annotationGlobals\");\n      if (!annotationGlobals) {\n        return [];\n      }\n      const annotationPromises = [];\n      for (const annotationRef of annots) {\n        annotationPromises.push(AnnotationFactory.create(this.xref, annotationRef, annotationGlobals, this._localIdFactory, false, this.ref).catch(function (reason) {\n          warn(`_parsedAnnotations: \"${reason}\".`);\n          return null;\n        }));\n      }\n      const sortedAnnotations = [];\n      let popupAnnotations, widgetAnnotations;\n      for (const annotation of await Promise.all(annotationPromises)) {\n        if (!annotation) {\n          continue;\n        }\n        if (annotation instanceof WidgetAnnotation) {\n          (widgetAnnotations ||= []).push(annotation);\n          continue;\n        }\n        if (annotation instanceof PopupAnnotation) {\n          (popupAnnotations ||= []).push(annotation);\n          continue;\n        }\n        sortedAnnotations.push(annotation);\n      }\n      if (widgetAnnotations) {\n        sortedAnnotations.push(...widgetAnnotations);\n      }\n      if (popupAnnotations) {\n        sortedAnnotations.push(...popupAnnotations);\n      }\n      return sortedAnnotations;\n    });\n    return shadow(this, \"_parsedAnnotations\", promise);\n  }\n  get jsActions() {\n    const actions = collectActions(this.xref, this.pageDict, PageActionEventType);\n    return shadow(this, \"jsActions\", actions);\n  }\n}\nconst PDF_HEADER_SIGNATURE = new Uint8Array([0x25, 0x50, 0x44, 0x46, 0x2d]);\nconst STARTXREF_SIGNATURE = new Uint8Array([0x73, 0x74, 0x61, 0x72, 0x74, 0x78, 0x72, 0x65, 0x66]);\nconst ENDOBJ_SIGNATURE = new Uint8Array([0x65, 0x6e, 0x64, 0x6f, 0x62, 0x6a]);\nconst FINGERPRINT_FIRST_BYTES = 1024;\nconst EMPTY_FINGERPRINT = \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\";\nfunction find(stream, signature, limit = 1024, backwards = false) {\n  const signatureLength = signature.length;\n  const scanBytes = stream.peekBytes(limit);\n  const scanLength = scanBytes.length - signatureLength;\n  if (scanLength <= 0) {\n    return false;\n  }\n  if (backwards) {\n    const signatureEnd = signatureLength - 1;\n    let pos = scanBytes.length - 1;\n    while (pos >= signatureEnd) {\n      let j = 0;\n      while (j < signatureLength && scanBytes[pos - j] === signature[signatureEnd - j]) {\n        j++;\n      }\n      if (j >= signatureLength) {\n        stream.pos += pos - signatureEnd;\n        return true;\n      }\n      pos--;\n    }\n  } else {\n    let pos = 0;\n    while (pos <= scanLength) {\n      let j = 0;\n      while (j < signatureLength && scanBytes[pos + j] === signature[j]) {\n        j++;\n      }\n      if (j >= signatureLength) {\n        stream.pos += pos;\n        return true;\n      }\n      pos++;\n    }\n  }\n  return false;\n}\nclass PDFDocument {\n  constructor(pdfManager, stream) {\n    if (stream.length <= 0) {\n      throw new InvalidPDFException(\"The PDF file is empty, i.e. its size is zero bytes.\");\n    }\n    this.pdfManager = pdfManager;\n    this.stream = stream;\n    this.xref = new XRef(stream, pdfManager);\n    this._pagePromises = new Map();\n    this._version = null;\n    const idCounters = {\n      font: 0\n    };\n    this._globalIdFactory = class {\n      static getDocId() {\n        return `g_${pdfManager.docId}`;\n      }\n      static createFontId() {\n        return `f${++idCounters.font}`;\n      }\n      static createObjId() {\n        unreachable(\"Abstract method `createObjId` called.\");\n      }\n      static getPageObjId() {\n        unreachable(\"Abstract method `getPageObjId` called.\");\n      }\n    };\n  }\n  parse(recoveryMode) {\n    this.xref.parse(recoveryMode);\n    this.catalog = new Catalog(this.pdfManager, this.xref);\n  }\n  get linearization() {\n    let linearization = null;\n    try {\n      linearization = Linearization.create(this.stream);\n    } catch (err) {\n      if (err instanceof MissingDataException) {\n        throw err;\n      }\n      info(err);\n    }\n    return shadow(this, \"linearization\", linearization);\n  }\n  get startXRef() {\n    const stream = this.stream;\n    let startXRef = 0;\n    if (this.linearization) {\n      stream.reset();\n      if (find(stream, ENDOBJ_SIGNATURE)) {\n        stream.skip(6);\n        let ch = stream.peekByte();\n        while (isWhiteSpace(ch)) {\n          stream.pos++;\n          ch = stream.peekByte();\n        }\n        startXRef = stream.pos - stream.start;\n      }\n    } else {\n      const step = 1024;\n      const startXRefLength = STARTXREF_SIGNATURE.length;\n      let found = false,\n        pos = stream.end;\n      while (!found && pos > 0) {\n        pos -= step - startXRefLength;\n        if (pos < 0) {\n          pos = 0;\n        }\n        stream.pos = pos;\n        found = find(stream, STARTXREF_SIGNATURE, step, true);\n      }\n      if (found) {\n        stream.skip(9);\n        let ch;\n        do {\n          ch = stream.getByte();\n        } while (isWhiteSpace(ch));\n        let str = \"\";\n        while (ch >= 0x20 && ch <= 0x39) {\n          str += String.fromCharCode(ch);\n          ch = stream.getByte();\n        }\n        startXRef = parseInt(str, 10);\n        if (isNaN(startXRef)) {\n          startXRef = 0;\n        }\n      }\n    }\n    return shadow(this, \"startXRef\", startXRef);\n  }\n  checkHeader() {\n    const stream = this.stream;\n    stream.reset();\n    if (!find(stream, PDF_HEADER_SIGNATURE)) {\n      return;\n    }\n    stream.moveStart();\n    stream.skip(PDF_HEADER_SIGNATURE.length);\n    let version = \"\",\n      ch;\n    while ((ch = stream.getByte()) > 0x20 && version.length < 7) {\n      version += String.fromCharCode(ch);\n    }\n    if (PDF_VERSION_REGEXP.test(version)) {\n      this._version = version;\n    } else {\n      warn(`Invalid PDF header version: ${version}`);\n    }\n  }\n  parseStartXRef() {\n    this.xref.setStartXRef(this.startXRef);\n  }\n  get numPages() {\n    let num = 0;\n    if (this.catalog.hasActualNumPages) {\n      num = this.catalog.numPages;\n    } else if (this.xfaFactory) {\n      num = this.xfaFactory.getNumPages();\n    } else if (this.linearization) {\n      num = this.linearization.numPages;\n    } else {\n      num = this.catalog.numPages;\n    }\n    return shadow(this, \"numPages\", num);\n  }\n  _hasOnlyDocumentSignatures(fields, recursionDepth = 0) {\n    const RECURSION_LIMIT = 10;\n    if (!Array.isArray(fields)) {\n      return false;\n    }\n    return fields.every(field => {\n      field = this.xref.fetchIfRef(field);\n      if (!(field instanceof Dict)) {\n        return false;\n      }\n      if (field.has(\"Kids\")) {\n        if (++recursionDepth > RECURSION_LIMIT) {\n          warn(\"_hasOnlyDocumentSignatures: maximum recursion depth reached\");\n          return false;\n        }\n        return this._hasOnlyDocumentSignatures(field.get(\"Kids\"), recursionDepth);\n      }\n      const isSignature = isName(field.get(\"FT\"), \"Sig\");\n      const rectangle = field.get(\"Rect\");\n      const isInvisible = Array.isArray(rectangle) && rectangle.every(value => value === 0);\n      return isSignature && isInvisible;\n    });\n  }\n  get _xfaStreams() {\n    const acroForm = this.catalog.acroForm;\n    if (!acroForm) {\n      return null;\n    }\n    const xfa = acroForm.get(\"XFA\");\n    const entries = {\n      \"xdp:xdp\": \"\",\n      template: \"\",\n      datasets: \"\",\n      config: \"\",\n      connectionSet: \"\",\n      localeSet: \"\",\n      stylesheet: \"\",\n      \"/xdp:xdp\": \"\"\n    };\n    if (xfa instanceof BaseStream && !xfa.isEmpty) {\n      entries[\"xdp:xdp\"] = xfa;\n      return entries;\n    }\n    if (!Array.isArray(xfa) || xfa.length === 0) {\n      return null;\n    }\n    for (let i = 0, ii = xfa.length; i < ii; i += 2) {\n      let name;\n      if (i === 0) {\n        name = \"xdp:xdp\";\n      } else if (i === ii - 2) {\n        name = \"/xdp:xdp\";\n      } else {\n        name = xfa[i];\n      }\n      if (!entries.hasOwnProperty(name)) {\n        continue;\n      }\n      const data = this.xref.fetchIfRef(xfa[i + 1]);\n      if (!(data instanceof BaseStream) || data.isEmpty) {\n        continue;\n      }\n      entries[name] = data;\n    }\n    return entries;\n  }\n  get xfaDatasets() {\n    const streams = this._xfaStreams;\n    if (!streams) {\n      return shadow(this, \"xfaDatasets\", null);\n    }\n    for (const key of [\"datasets\", \"xdp:xdp\"]) {\n      const stream = streams[key];\n      if (!stream) {\n        continue;\n      }\n      try {\n        const str = stringToUTF8String(stream.getString());\n        const data = {\n          [key]: str\n        };\n        return shadow(this, \"xfaDatasets\", new DatasetReader(data));\n      } catch {\n        warn(\"XFA - Invalid utf-8 string.\");\n        break;\n      }\n    }\n    return shadow(this, \"xfaDatasets\", null);\n  }\n  get xfaData() {\n    const streams = this._xfaStreams;\n    if (!streams) {\n      return null;\n    }\n    const data = Object.create(null);\n    for (const [key, stream] of Object.entries(streams)) {\n      if (!stream) {\n        continue;\n      }\n      try {\n        data[key] = stringToUTF8String(stream.getString());\n      } catch {\n        warn(\"XFA - Invalid utf-8 string.\");\n        return null;\n      }\n    }\n    return data;\n  }\n  get xfaFactory() {\n    let data;\n    if (this.pdfManager.enableXfa && this.catalog.needsRendering && this.formInfo.hasXfa && !this.formInfo.hasAcroForm) {\n      data = this.xfaData;\n    }\n    return shadow(this, \"xfaFactory\", data ? new XFAFactory(data) : null);\n  }\n  get isPureXfa() {\n    return this.xfaFactory ? this.xfaFactory.isValid() : false;\n  }\n  get htmlForXfa() {\n    return this.xfaFactory ? this.xfaFactory.getPages() : null;\n  }\n  async loadXfaImages() {\n    const xfaImagesDict = await this.pdfManager.ensureCatalog(\"xfaImages\");\n    if (!xfaImagesDict) {\n      return;\n    }\n    const keys = xfaImagesDict.getKeys();\n    const objectLoader = new ObjectLoader(xfaImagesDict, keys, this.xref);\n    await objectLoader.load();\n    const xfaImages = new Map();\n    for (const key of keys) {\n      const stream = xfaImagesDict.get(key);\n      if (stream instanceof BaseStream) {\n        xfaImages.set(key, stream.getBytes());\n      }\n    }\n    this.xfaFactory.setImages(xfaImages);\n  }\n  async loadXfaFonts(handler, task) {\n    const acroForm = await this.pdfManager.ensureCatalog(\"acroForm\");\n    if (!acroForm) {\n      return;\n    }\n    const resources = await acroForm.getAsync(\"DR\");\n    if (!(resources instanceof Dict)) {\n      return;\n    }\n    const objectLoader = new ObjectLoader(resources, [\"Font\"], this.xref);\n    await objectLoader.load();\n    const fontRes = resources.get(\"Font\");\n    if (!(fontRes instanceof Dict)) {\n      return;\n    }\n    const options = Object.assign(Object.create(null), this.pdfManager.evaluatorOptions);\n    options.useSystemFonts = false;\n    const partialEvaluator = new PartialEvaluator({\n      xref: this.xref,\n      handler,\n      pageIndex: -1,\n      idFactory: this._globalIdFactory,\n      fontCache: this.catalog.fontCache,\n      builtInCMapCache: this.catalog.builtInCMapCache,\n      standardFontDataCache: this.catalog.standardFontDataCache,\n      options\n    });\n    const operatorList = new OperatorList();\n    const pdfFonts = [];\n    const initialState = {\n      get font() {\n        return pdfFonts.at(-1);\n      },\n      set font(font) {\n        pdfFonts.push(font);\n      },\n      clone() {\n        return this;\n      }\n    };\n    const fonts = new Map();\n    fontRes.forEach((fontName, font) => {\n      fonts.set(fontName, font);\n    });\n    const promises = [];\n    for (const [fontName, font] of fonts) {\n      const descriptor = font.get(\"FontDescriptor\");\n      if (!(descriptor instanceof Dict)) {\n        continue;\n      }\n      let fontFamily = descriptor.get(\"FontFamily\");\n      fontFamily = fontFamily.replaceAll(/[ ]+(\\d)/g, \"$1\");\n      const fontWeight = descriptor.get(\"FontWeight\");\n      const italicAngle = -descriptor.get(\"ItalicAngle\");\n      const cssFontInfo = {\n        fontFamily,\n        fontWeight,\n        italicAngle\n      };\n      if (!validateCSSFont(cssFontInfo)) {\n        continue;\n      }\n      promises.push(partialEvaluator.handleSetFont(resources, [Name.get(fontName), 1], null, operatorList, task, initialState, null, cssFontInfo).catch(function (reason) {\n        warn(`loadXfaFonts: \"${reason}\".`);\n        return null;\n      }));\n    }\n    await Promise.all(promises);\n    const missingFonts = this.xfaFactory.setFonts(pdfFonts);\n    if (!missingFonts) {\n      return;\n    }\n    options.ignoreErrors = true;\n    promises.length = 0;\n    pdfFonts.length = 0;\n    const reallyMissingFonts = new Set();\n    for (const missing of missingFonts) {\n      if (!getXfaFontName(`${missing}-Regular`)) {\n        reallyMissingFonts.add(missing);\n      }\n    }\n    if (reallyMissingFonts.size) {\n      missingFonts.push(\"PdfJS-Fallback\");\n    }\n    for (const missing of missingFonts) {\n      if (reallyMissingFonts.has(missing)) {\n        continue;\n      }\n      for (const fontInfo of [{\n        name: \"Regular\",\n        fontWeight: 400,\n        italicAngle: 0\n      }, {\n        name: \"Bold\",\n        fontWeight: 700,\n        italicAngle: 0\n      }, {\n        name: \"Italic\",\n        fontWeight: 400,\n        italicAngle: 12\n      }, {\n        name: \"BoldItalic\",\n        fontWeight: 700,\n        italicAngle: 12\n      }]) {\n        const name = `${missing}-${fontInfo.name}`;\n        const dict = getXfaFontDict(name);\n        promises.push(partialEvaluator.handleSetFont(resources, [Name.get(name), 1], null, operatorList, task, initialState, dict, {\n          fontFamily: missing,\n          fontWeight: fontInfo.fontWeight,\n          italicAngle: fontInfo.italicAngle\n        }).catch(function (reason) {\n          warn(`loadXfaFonts: \"${reason}\".`);\n          return null;\n        }));\n      }\n    }\n    await Promise.all(promises);\n    this.xfaFactory.appendFonts(pdfFonts, reallyMissingFonts);\n  }\n  async serializeXfaData(annotationStorage) {\n    return this.xfaFactory ? this.xfaFactory.serializeData(annotationStorage) : null;\n  }\n  get version() {\n    return this.catalog.version || this._version;\n  }\n  get formInfo() {\n    const formInfo = {\n      hasFields: false,\n      hasAcroForm: false,\n      hasXfa: false,\n      hasSignatures: false\n    };\n    const acroForm = this.catalog.acroForm;\n    if (!acroForm) {\n      return shadow(this, \"formInfo\", formInfo);\n    }\n    try {\n      const fields = acroForm.get(\"Fields\");\n      const hasFields = Array.isArray(fields) && fields.length > 0;\n      formInfo.hasFields = hasFields;\n      const xfa = acroForm.get(\"XFA\");\n      formInfo.hasXfa = Array.isArray(xfa) && xfa.length > 0 || xfa instanceof BaseStream && !xfa.isEmpty;\n      const sigFlags = acroForm.get(\"SigFlags\");\n      const hasSignatures = !!(sigFlags & 0x1);\n      const hasOnlyDocumentSignatures = hasSignatures && this._hasOnlyDocumentSignatures(fields);\n      formInfo.hasAcroForm = hasFields && !hasOnlyDocumentSignatures;\n      formInfo.hasSignatures = hasSignatures;\n    } catch (ex) {\n      if (ex instanceof MissingDataException) {\n        throw ex;\n      }\n      warn(`Cannot fetch form information: \"${ex}\".`);\n    }\n    return shadow(this, \"formInfo\", formInfo);\n  }\n  get documentInfo() {\n    const docInfo = {\n      PDFFormatVersion: this.version,\n      Language: this.catalog.lang,\n      EncryptFilterName: this.xref.encrypt ? this.xref.encrypt.filterName : null,\n      IsLinearized: !!this.linearization,\n      IsAcroFormPresent: this.formInfo.hasAcroForm,\n      IsXFAPresent: this.formInfo.hasXfa,\n      IsCollectionPresent: !!this.catalog.collection,\n      IsSignaturesPresent: this.formInfo.hasSignatures\n    };\n    let infoDict;\n    try {\n      infoDict = this.xref.trailer.get(\"Info\");\n    } catch (err) {\n      if (err instanceof MissingDataException) {\n        throw err;\n      }\n      info(\"The document information dictionary is invalid.\");\n    }\n    if (!(infoDict instanceof Dict)) {\n      return shadow(this, \"documentInfo\", docInfo);\n    }\n    for (const key of infoDict.getKeys()) {\n      const value = infoDict.get(key);\n      switch (key) {\n        case \"Title\":\n        case \"Author\":\n        case \"Subject\":\n        case \"Keywords\":\n        case \"Creator\":\n        case \"Producer\":\n        case \"CreationDate\":\n        case \"ModDate\":\n          if (typeof value === \"string\") {\n            docInfo[key] = stringToPDFString(value);\n            continue;\n          }\n          break;\n        case \"Trapped\":\n          if (value instanceof Name) {\n            docInfo[key] = value;\n            continue;\n          }\n          break;\n        default:\n          let customValue;\n          switch (typeof value) {\n            case \"string\":\n              customValue = stringToPDFString(value);\n              break;\n            case \"number\":\n            case \"boolean\":\n              customValue = value;\n              break;\n            default:\n              if (value instanceof Name) {\n                customValue = value;\n              }\n              break;\n          }\n          if (customValue === undefined) {\n            warn(`Bad value, for custom key \"${key}\", in Info: ${value}.`);\n            continue;\n          }\n          if (!docInfo.Custom) {\n            docInfo.Custom = Object.create(null);\n          }\n          docInfo.Custom[key] = customValue;\n          continue;\n      }\n      warn(`Bad value, for key \"${key}\", in Info: ${value}.`);\n    }\n    return shadow(this, \"documentInfo\", docInfo);\n  }\n  get fingerprints() {\n    function validate(data) {\n      return typeof data === \"string\" && data.length > 0 && data !== EMPTY_FINGERPRINT;\n    }\n    function hexString(hash) {\n      const buf = [];\n      for (const num of hash) {\n        const hex = num.toString(16);\n        buf.push(hex.padStart(2, \"0\"));\n      }\n      return buf.join(\"\");\n    }\n    const idArray = this.xref.trailer.get(\"ID\");\n    let hashOriginal, hashModified;\n    if (Array.isArray(idArray) && validate(idArray[0])) {\n      hashOriginal = stringToBytes(idArray[0]);\n      if (idArray[1] !== idArray[0] && validate(idArray[1])) {\n        hashModified = stringToBytes(idArray[1]);\n      }\n    } else {\n      hashOriginal = calculateMD5(this.stream.getByteRange(0, FINGERPRINT_FIRST_BYTES), 0, FINGERPRINT_FIRST_BYTES);\n    }\n    return shadow(this, \"fingerprints\", [hexString(hashOriginal), hashModified ? hexString(hashModified) : null]);\n  }\n  async _getLinearizationPage(pageIndex) {\n    const {\n      catalog,\n      linearization,\n      xref\n    } = this;\n    const ref = Ref.get(linearization.objectNumberFirst, 0);\n    try {\n      const obj = await xref.fetchAsync(ref);\n      if (obj instanceof Dict) {\n        let type = obj.getRaw(\"Type\");\n        if (type instanceof Ref) {\n          type = await xref.fetchAsync(type);\n        }\n        if (isName(type, \"Page\") || !obj.has(\"Type\") && !obj.has(\"Kids\")) {\n          if (!catalog.pageKidsCountCache.has(ref)) {\n            catalog.pageKidsCountCache.put(ref, 1);\n          }\n          if (!catalog.pageIndexCache.has(ref)) {\n            catalog.pageIndexCache.put(ref, 0);\n          }\n          return [obj, ref];\n        }\n      }\n      throw new FormatError(\"The Linearization dictionary doesn't point to a valid Page dictionary.\");\n    } catch (reason) {\n      warn(`_getLinearizationPage: \"${reason.message}\".`);\n      return catalog.getPageDict(pageIndex);\n    }\n  }\n  getPage(pageIndex) {\n    const cachedPromise = this._pagePromises.get(pageIndex);\n    if (cachedPromise) {\n      return cachedPromise;\n    }\n    const {\n      catalog,\n      linearization,\n      xfaFactory\n    } = this;\n    let promise;\n    if (xfaFactory) {\n      promise = Promise.resolve([Dict.empty, null]);\n    } else if (linearization?.pageFirst === pageIndex) {\n      promise = this._getLinearizationPage(pageIndex);\n    } else {\n      promise = catalog.getPageDict(pageIndex);\n    }\n    promise = promise.then(([pageDict, ref]) => {\n      return new Page({\n        pdfManager: this.pdfManager,\n        xref: this.xref,\n        pageIndex,\n        pageDict,\n        ref,\n        globalIdFactory: this._globalIdFactory,\n        fontCache: catalog.fontCache,\n        builtInCMapCache: catalog.builtInCMapCache,\n        standardFontDataCache: catalog.standardFontDataCache,\n        globalImageCache: catalog.globalImageCache,\n        systemFontCache: catalog.systemFontCache,\n        nonBlendModesSet: catalog.nonBlendModesSet,\n        xfaFactory\n      });\n    });\n    return promise;\n  }\n  async checkFirstPage(recoveryMode = false) {\n    if (recoveryMode) {\n      return;\n    }\n    try {\n      await this.getPage(0);\n    } catch (reason) {\n      if (reason instanceof XRefEntryException) {\n        this._pagePromises.delete(0);\n        await this.cleanup();\n        throw new XRefParseException();\n      }\n    }\n  }\n  async checkLastPage(recoveryMode = false) {\n    const {\n      catalog,\n      pdfManager\n    } = this;\n    catalog.setActualNumPages();\n    let numPages;\n    try {\n      await Promise.all([pdfManager.ensureDoc(\"xfaFactory\"), pdfManager.ensureDoc(\"linearization\"), pdfManager.ensureCatalog(\"numPages\")]);\n      if (this.xfaFactory) {\n        return;\n      } else if (this.linearization) {\n        numPages = this.linearization.numPages;\n      } else {\n        numPages = catalog.numPages;\n      }\n      if (!Number.isInteger(numPages)) {\n        throw new FormatError(\"Page count is not an integer.\");\n      } else if (numPages <= 1) {\n        return;\n      }\n      await this.getPage(numPages - 1);\n    } catch (reason) {\n      this._pagePromises.delete(numPages - 1);\n      await this.cleanup();\n      if (reason instanceof XRefEntryException && !recoveryMode) {\n        throw new XRefParseException();\n      }\n      warn(`checkLastPage - invalid /Pages tree /Count: ${numPages}.`);\n      let pagesTree;\n      try {\n        pagesTree = await catalog.getAllPageDicts(recoveryMode);\n      } catch (reasonAll) {\n        if (reasonAll instanceof XRefEntryException && !recoveryMode) {\n          throw new XRefParseException();\n        }\n        catalog.setActualNumPages(1);\n        return;\n      }\n      for (const [pageIndex, [pageDict, ref]] of pagesTree) {\n        let promise;\n        if (pageDict instanceof Error) {\n          promise = Promise.reject(pageDict);\n          promise.catch(() => {});\n        } else {\n          promise = Promise.resolve(new Page({\n            pdfManager,\n            xref: this.xref,\n            pageIndex,\n            pageDict,\n            ref,\n            globalIdFactory: this._globalIdFactory,\n            fontCache: catalog.fontCache,\n            builtInCMapCache: catalog.builtInCMapCache,\n            standardFontDataCache: catalog.standardFontDataCache,\n            globalImageCache: catalog.globalImageCache,\n            systemFontCache: catalog.systemFontCache,\n            nonBlendModesSet: catalog.nonBlendModesSet,\n            xfaFactory: null\n          }));\n        }\n        this._pagePromises.set(pageIndex, promise);\n      }\n      catalog.setActualNumPages(pagesTree.size);\n    }\n  }\n  fontFallback(id, handler) {\n    return this.catalog.fontFallback(id, handler);\n  }\n  async cleanup(manuallyTriggered = false) {\n    return this.catalog ? this.catalog.cleanup(manuallyTriggered) : clearGlobalCaches();\n  }\n  async #collectFieldObjects(name, fieldRef, promises, annotationGlobals, visitedRefs) {\n    const {\n      xref\n    } = this;\n    if (!(fieldRef instanceof Ref) || visitedRefs.has(fieldRef)) {\n      return;\n    }\n    visitedRefs.put(fieldRef);\n    const field = await xref.fetchAsync(fieldRef);\n    if (!(field instanceof Dict)) {\n      return;\n    }\n    if (field.has(\"T\")) {\n      const partName = stringToPDFString(await field.getAsync(\"T\"));\n      name = name === \"\" ? partName : `${name}.${partName}`;\n    } else {\n      let obj = field;\n      while (true) {\n        obj = obj.getRaw(\"Parent\");\n        if (obj instanceof Ref) {\n          if (visitedRefs.has(obj)) {\n            break;\n          }\n          obj = await xref.fetchAsync(obj);\n        }\n        if (!(obj instanceof Dict)) {\n          break;\n        }\n        if (obj.has(\"T\")) {\n          const partName = stringToPDFString(await obj.getAsync(\"T\"));\n          name = name === \"\" ? partName : `${name}.${partName}`;\n          break;\n        }\n      }\n    }\n    if (!promises.has(name)) {\n      promises.set(name, []);\n    }\n    promises.get(name).push(AnnotationFactory.create(xref, fieldRef, annotationGlobals, null, true, null).then(annotation => annotation?.getFieldObject()).catch(function (reason) {\n      warn(`#collectFieldObjects: \"${reason}\".`);\n      return null;\n    }));\n    if (!field.has(\"Kids\")) {\n      return;\n    }\n    const kids = await field.getAsync(\"Kids\");\n    if (Array.isArray(kids)) {\n      for (const kid of kids) {\n        await this.#collectFieldObjects(name, kid, promises, annotationGlobals, visitedRefs);\n      }\n    }\n  }\n  get fieldObjects() {\n    if (!this.formInfo.hasFields) {\n      return shadow(this, \"fieldObjects\", Promise.resolve(null));\n    }\n    const promise = Promise.all([this.pdfManager.ensureDoc(\"annotationGlobals\"), this.pdfManager.ensureCatalog(\"acroForm\")]).then(async ([annotationGlobals, acroForm]) => {\n      if (!annotationGlobals) {\n        return null;\n      }\n      const visitedRefs = new RefSet();\n      const allFields = Object.create(null);\n      const fieldPromises = new Map();\n      for (const fieldRef of await acroForm.getAsync(\"Fields\")) {\n        await this.#collectFieldObjects(\"\", fieldRef, fieldPromises, annotationGlobals, visitedRefs);\n      }\n      const allPromises = [];\n      for (const [name, promises] of fieldPromises) {\n        allPromises.push(Promise.all(promises).then(fields => {\n          fields = fields.filter(field => !!field);\n          if (fields.length > 0) {\n            allFields[name] = fields;\n          }\n        }));\n      }\n      await Promise.all(allPromises);\n      return allFields;\n    });\n    return shadow(this, \"fieldObjects\", promise);\n  }\n  get hasJSActions() {\n    const promise = this.pdfManager.ensureDoc(\"_parseHasJSActions\");\n    return shadow(this, \"hasJSActions\", promise);\n  }\n  async _parseHasJSActions() {\n    const [catalogJsActions, fieldObjects] = await Promise.all([this.pdfManager.ensureCatalog(\"jsActions\"), this.pdfManager.ensureDoc(\"fieldObjects\")]);\n    if (catalogJsActions) {\n      return true;\n    }\n    if (fieldObjects) {\n      return Object.values(fieldObjects).some(fieldObject => fieldObject.some(object => object.actions !== null));\n    }\n    return false;\n  }\n  get calculationOrderIds() {\n    const acroForm = this.catalog.acroForm;\n    if (!acroForm?.has(\"CO\")) {\n      return shadow(this, \"calculationOrderIds\", null);\n    }\n    const calculationOrder = acroForm.get(\"CO\");\n    if (!Array.isArray(calculationOrder) || calculationOrder.length === 0) {\n      return shadow(this, \"calculationOrderIds\", null);\n    }\n    const ids = [];\n    for (const id of calculationOrder) {\n      if (id instanceof Ref) {\n        ids.push(id.toString());\n      }\n    }\n    if (ids.length === 0) {\n      return shadow(this, \"calculationOrderIds\", null);\n    }\n    return shadow(this, \"calculationOrderIds\", ids);\n  }\n  get annotationGlobals() {\n    return shadow(this, \"annotationGlobals\", AnnotationFactory.createGlobals(this.pdfManager));\n  }\n}\n\n;// ./src/core/pdf_manager.js\n\n\n\n\n\nfunction parseDocBaseUrl(url) {\n  if (url) {\n    const absoluteUrl = createValidAbsoluteUrl(url);\n    if (absoluteUrl) {\n      return absoluteUrl.href;\n    }\n    warn(`Invalid absolute docBaseUrl: \"${url}\".`);\n  }\n  return null;\n}\nclass BasePdfManager {\n  constructor(args) {\n    if (this.constructor === BasePdfManager) {\n      unreachable(\"Cannot initialize BasePdfManager.\");\n    }\n    this._docBaseUrl = parseDocBaseUrl(args.docBaseUrl);\n    this._docId = args.docId;\n    this._password = args.password;\n    this.enableXfa = args.enableXfa;\n    args.evaluatorOptions.isOffscreenCanvasSupported &&= FeatureTest.isOffscreenCanvasSupported;\n    this.evaluatorOptions = args.evaluatorOptions;\n  }\n  get docId() {\n    return this._docId;\n  }\n  get password() {\n    return this._password;\n  }\n  get docBaseUrl() {\n    return this._docBaseUrl;\n  }\n  get catalog() {\n    return this.pdfDocument.catalog;\n  }\n  ensureDoc(prop, args) {\n    return this.ensure(this.pdfDocument, prop, args);\n  }\n  ensureXRef(prop, args) {\n    return this.ensure(this.pdfDocument.xref, prop, args);\n  }\n  ensureCatalog(prop, args) {\n    return this.ensure(this.pdfDocument.catalog, prop, args);\n  }\n  getPage(pageIndex) {\n    return this.pdfDocument.getPage(pageIndex);\n  }\n  fontFallback(id, handler) {\n    return this.pdfDocument.fontFallback(id, handler);\n  }\n  loadXfaFonts(handler, task) {\n    return this.pdfDocument.loadXfaFonts(handler, task);\n  }\n  loadXfaImages() {\n    return this.pdfDocument.loadXfaImages();\n  }\n  serializeXfaData(annotationStorage) {\n    return this.pdfDocument.serializeXfaData(annotationStorage);\n  }\n  cleanup(manuallyTriggered = false) {\n    return this.pdfDocument.cleanup(manuallyTriggered);\n  }\n  async ensure(obj, prop, args) {\n    unreachable(\"Abstract method `ensure` called\");\n  }\n  requestRange(begin, end) {\n    unreachable(\"Abstract method `requestRange` called\");\n  }\n  requestLoadedStream(noFetch = false) {\n    unreachable(\"Abstract method `requestLoadedStream` called\");\n  }\n  sendProgressiveData(chunk) {\n    unreachable(\"Abstract method `sendProgressiveData` called\");\n  }\n  updatePassword(password) {\n    this._password = password;\n  }\n  terminate(reason) {\n    unreachable(\"Abstract method `terminate` called\");\n  }\n}\nclass LocalPdfManager extends BasePdfManager {\n  constructor(args) {\n    super(args);\n    const stream = new Stream(args.source);\n    this.pdfDocument = new PDFDocument(this, stream);\n    this._loadedStreamPromise = Promise.resolve(stream);\n  }\n  async ensure(obj, prop, args) {\n    const value = obj[prop];\n    if (typeof value === \"function\") {\n      return value.apply(obj, args);\n    }\n    return value;\n  }\n  requestRange(begin, end) {\n    return Promise.resolve();\n  }\n  requestLoadedStream(noFetch = false) {\n    return this._loadedStreamPromise;\n  }\n  terminate(reason) {}\n}\nclass NetworkPdfManager extends BasePdfManager {\n  constructor(args) {\n    super(args);\n    this.streamManager = new ChunkedStreamManager(args.source, {\n      msgHandler: args.handler,\n      length: args.length,\n      disableAutoFetch: args.disableAutoFetch,\n      rangeChunkSize: args.rangeChunkSize\n    });\n    this.pdfDocument = new PDFDocument(this, this.streamManager.getStream());\n  }\n  async ensure(obj, prop, args) {\n    try {\n      const value = obj[prop];\n      if (typeof value === \"function\") {\n        return value.apply(obj, args);\n      }\n      return value;\n    } catch (ex) {\n      if (!(ex instanceof MissingDataException)) {\n        throw ex;\n      }\n      await this.requestRange(ex.begin, ex.end);\n      return this.ensure(obj, prop, args);\n    }\n  }\n  requestRange(begin, end) {\n    return this.streamManager.requestRange(begin, end);\n  }\n  requestLoadedStream(noFetch = false) {\n    return this.streamManager.requestAllChunks(noFetch);\n  }\n  sendProgressiveData(chunk) {\n    this.streamManager.onReceiveData({\n      chunk\n    });\n  }\n  terminate(reason) {\n    this.streamManager.abort(reason);\n  }\n}\n\n;// ./src/shared/message_handler.js\n\nconst CallbackKind = {\n  UNKNOWN: 0,\n  DATA: 1,\n  ERROR: 2\n};\nconst StreamKind = {\n  UNKNOWN: 0,\n  CANCEL: 1,\n  CANCEL_COMPLETE: 2,\n  CLOSE: 3,\n  ENQUEUE: 4,\n  ERROR: 5,\n  PULL: 6,\n  PULL_COMPLETE: 7,\n  START_COMPLETE: 8\n};\nfunction wrapReason(reason) {\n  if (!(reason instanceof Error || typeof reason === \"object\" && reason !== null)) {\n    unreachable('wrapReason: Expected \"reason\" to be a (possibly cloned) Error.');\n  }\n  switch (reason.name) {\n    case \"AbortException\":\n      return new AbortException(reason.message);\n    case \"MissingPDFException\":\n      return new MissingPDFException(reason.message);\n    case \"PasswordException\":\n      return new PasswordException(reason.message, reason.code);\n    case \"UnexpectedResponseException\":\n      return new UnexpectedResponseException(reason.message, reason.status);\n    case \"UnknownErrorException\":\n      return new UnknownErrorException(reason.message, reason.details);\n    default:\n      return new UnknownErrorException(reason.message, reason.toString());\n  }\n}\nclass MessageHandler {\n  constructor(sourceName, targetName, comObj) {\n    this.sourceName = sourceName;\n    this.targetName = targetName;\n    this.comObj = comObj;\n    this.callbackId = 1;\n    this.streamId = 1;\n    this.streamSinks = Object.create(null);\n    this.streamControllers = Object.create(null);\n    this.callbackCapabilities = Object.create(null);\n    this.actionHandler = Object.create(null);\n    this._onComObjOnMessage = event => {\n      const data = event.data;\n      if (data.targetName !== this.sourceName) {\n        return;\n      }\n      if (data.stream) {\n        this.#processStreamMessage(data);\n        return;\n      }\n      if (data.callback) {\n        const callbackId = data.callbackId;\n        const capability = this.callbackCapabilities[callbackId];\n        if (!capability) {\n          throw new Error(`Cannot resolve callback ${callbackId}`);\n        }\n        delete this.callbackCapabilities[callbackId];\n        if (data.callback === CallbackKind.DATA) {\n          capability.resolve(data.data);\n        } else if (data.callback === CallbackKind.ERROR) {\n          capability.reject(wrapReason(data.reason));\n        } else {\n          throw new Error(\"Unexpected callback case\");\n        }\n        return;\n      }\n      const action = this.actionHandler[data.action];\n      if (!action) {\n        throw new Error(`Unknown action from worker: ${data.action}`);\n      }\n      if (data.callbackId) {\n        const cbSourceName = this.sourceName;\n        const cbTargetName = data.sourceName;\n        new Promise(function (resolve) {\n          resolve(action(data.data));\n        }).then(function (result) {\n          comObj.postMessage({\n            sourceName: cbSourceName,\n            targetName: cbTargetName,\n            callback: CallbackKind.DATA,\n            callbackId: data.callbackId,\n            data: result\n          });\n        }, function (reason) {\n          comObj.postMessage({\n            sourceName: cbSourceName,\n            targetName: cbTargetName,\n            callback: CallbackKind.ERROR,\n            callbackId: data.callbackId,\n            reason: wrapReason(reason)\n          });\n        });\n        return;\n      }\n      if (data.streamId) {\n        this.#createStreamSink(data);\n        return;\n      }\n      action(data.data);\n    };\n    comObj.addEventListener(\"message\", this._onComObjOnMessage);\n  }\n  on(actionName, handler) {\n    const ah = this.actionHandler;\n    if (ah[actionName]) {\n      throw new Error(`There is already an actionName called \"${actionName}\"`);\n    }\n    ah[actionName] = handler;\n  }\n  send(actionName, data, transfers) {\n    this.comObj.postMessage({\n      sourceName: this.sourceName,\n      targetName: this.targetName,\n      action: actionName,\n      data\n    }, transfers);\n  }\n  sendWithPromise(actionName, data, transfers) {\n    const callbackId = this.callbackId++;\n    const capability = new PromiseCapability();\n    this.callbackCapabilities[callbackId] = capability;\n    try {\n      this.comObj.postMessage({\n        sourceName: this.sourceName,\n        targetName: this.targetName,\n        action: actionName,\n        callbackId,\n        data\n      }, transfers);\n    } catch (ex) {\n      capability.reject(ex);\n    }\n    return capability.promise;\n  }\n  sendWithStream(actionName, data, queueingStrategy, transfers) {\n    const streamId = this.streamId++,\n      sourceName = this.sourceName,\n      targetName = this.targetName,\n      comObj = this.comObj;\n    return new ReadableStream({\n      start: controller => {\n        const startCapability = new PromiseCapability();\n        this.streamControllers[streamId] = {\n          controller,\n          startCall: startCapability,\n          pullCall: null,\n          cancelCall: null,\n          isClosed: false\n        };\n        comObj.postMessage({\n          sourceName,\n          targetName,\n          action: actionName,\n          streamId,\n          data,\n          desiredSize: controller.desiredSize\n        }, transfers);\n        return startCapability.promise;\n      },\n      pull: controller => {\n        const pullCapability = new PromiseCapability();\n        this.streamControllers[streamId].pullCall = pullCapability;\n        comObj.postMessage({\n          sourceName,\n          targetName,\n          stream: StreamKind.PULL,\n          streamId,\n          desiredSize: controller.desiredSize\n        });\n        return pullCapability.promise;\n      },\n      cancel: reason => {\n        assert(reason instanceof Error, \"cancel must have a valid reason\");\n        const cancelCapability = new PromiseCapability();\n        this.streamControllers[streamId].cancelCall = cancelCapability;\n        this.streamControllers[streamId].isClosed = true;\n        comObj.postMessage({\n          sourceName,\n          targetName,\n          stream: StreamKind.CANCEL,\n          streamId,\n          reason: wrapReason(reason)\n        });\n        return cancelCapability.promise;\n      }\n    }, queueingStrategy);\n  }\n  #createStreamSink(data) {\n    const streamId = data.streamId,\n      sourceName = this.sourceName,\n      targetName = data.sourceName,\n      comObj = this.comObj;\n    const self = this,\n      action = this.actionHandler[data.action];\n    const streamSink = {\n      enqueue(chunk, size = 1, transfers) {\n        if (this.isCancelled) {\n          return;\n        }\n        const lastDesiredSize = this.desiredSize;\n        this.desiredSize -= size;\n        if (lastDesiredSize > 0 && this.desiredSize <= 0) {\n          this.sinkCapability = new PromiseCapability();\n          this.ready = this.sinkCapability.promise;\n        }\n        comObj.postMessage({\n          sourceName,\n          targetName,\n          stream: StreamKind.ENQUEUE,\n          streamId,\n          chunk\n        }, transfers);\n      },\n      close() {\n        if (this.isCancelled) {\n          return;\n        }\n        this.isCancelled = true;\n        comObj.postMessage({\n          sourceName,\n          targetName,\n          stream: StreamKind.CLOSE,\n          streamId\n        });\n        delete self.streamSinks[streamId];\n      },\n      error(reason) {\n        assert(reason instanceof Error, \"error must have a valid reason\");\n        if (this.isCancelled) {\n          return;\n        }\n        this.isCancelled = true;\n        comObj.postMessage({\n          sourceName,\n          targetName,\n          stream: StreamKind.ERROR,\n          streamId,\n          reason: wrapReason(reason)\n        });\n      },\n      sinkCapability: new PromiseCapability(),\n      onPull: null,\n      onCancel: null,\n      isCancelled: false,\n      desiredSize: data.desiredSize,\n      ready: null\n    };\n    streamSink.sinkCapability.resolve();\n    streamSink.ready = streamSink.sinkCapability.promise;\n    this.streamSinks[streamId] = streamSink;\n    new Promise(function (resolve) {\n      resolve(action(data.data, streamSink));\n    }).then(function () {\n      comObj.postMessage({\n        sourceName,\n        targetName,\n        stream: StreamKind.START_COMPLETE,\n        streamId,\n        success: true\n      });\n    }, function (reason) {\n      comObj.postMessage({\n        sourceName,\n        targetName,\n        stream: StreamKind.START_COMPLETE,\n        streamId,\n        reason: wrapReason(reason)\n      });\n    });\n  }\n  #processStreamMessage(data) {\n    const streamId = data.streamId,\n      sourceName = this.sourceName,\n      targetName = data.sourceName,\n      comObj = this.comObj;\n    const streamController = this.streamControllers[streamId],\n      streamSink = this.streamSinks[streamId];\n    switch (data.stream) {\n      case StreamKind.START_COMPLETE:\n        if (data.success) {\n          streamController.startCall.resolve();\n        } else {\n          streamController.startCall.reject(wrapReason(data.reason));\n        }\n        break;\n      case StreamKind.PULL_COMPLETE:\n        if (data.success) {\n          streamController.pullCall.resolve();\n        } else {\n          streamController.pullCall.reject(wrapReason(data.reason));\n        }\n        break;\n      case StreamKind.PULL:\n        if (!streamSink) {\n          comObj.postMessage({\n            sourceName,\n            targetName,\n            stream: StreamKind.PULL_COMPLETE,\n            streamId,\n            success: true\n          });\n          break;\n        }\n        if (streamSink.desiredSize <= 0 && data.desiredSize > 0) {\n          streamSink.sinkCapability.resolve();\n        }\n        streamSink.desiredSize = data.desiredSize;\n        new Promise(function (resolve) {\n          resolve(streamSink.onPull?.());\n        }).then(function () {\n          comObj.postMessage({\n            sourceName,\n            targetName,\n            stream: StreamKind.PULL_COMPLETE,\n            streamId,\n            success: true\n          });\n        }, function (reason) {\n          comObj.postMessage({\n            sourceName,\n            targetName,\n            stream: StreamKind.PULL_COMPLETE,\n            streamId,\n            reason: wrapReason(reason)\n          });\n        });\n        break;\n      case StreamKind.ENQUEUE:\n        assert(streamController, \"enqueue should have stream controller\");\n        if (streamController.isClosed) {\n          break;\n        }\n        streamController.controller.enqueue(data.chunk);\n        break;\n      case StreamKind.CLOSE:\n        assert(streamController, \"close should have stream controller\");\n        if (streamController.isClosed) {\n          break;\n        }\n        streamController.isClosed = true;\n        streamController.controller.close();\n        this.#deleteStreamController(streamController, streamId);\n        break;\n      case StreamKind.ERROR:\n        assert(streamController, \"error should have stream controller\");\n        streamController.controller.error(wrapReason(data.reason));\n        this.#deleteStreamController(streamController, streamId);\n        break;\n      case StreamKind.CANCEL_COMPLETE:\n        if (data.success) {\n          streamController.cancelCall.resolve();\n        } else {\n          streamController.cancelCall.reject(wrapReason(data.reason));\n        }\n        this.#deleteStreamController(streamController, streamId);\n        break;\n      case StreamKind.CANCEL:\n        if (!streamSink) {\n          break;\n        }\n        new Promise(function (resolve) {\n          resolve(streamSink.onCancel?.(wrapReason(data.reason)));\n        }).then(function () {\n          comObj.postMessage({\n            sourceName,\n            targetName,\n            stream: StreamKind.CANCEL_COMPLETE,\n            streamId,\n            success: true\n          });\n        }, function (reason) {\n          comObj.postMessage({\n            sourceName,\n            targetName,\n            stream: StreamKind.CANCEL_COMPLETE,\n            streamId,\n            reason: wrapReason(reason)\n          });\n        });\n        streamSink.sinkCapability.reject(wrapReason(data.reason));\n        streamSink.isCancelled = true;\n        delete this.streamSinks[streamId];\n        break;\n      default:\n        throw new Error(\"Unexpected stream case\");\n    }\n  }\n  async #deleteStreamController(streamController, streamId) {\n    await Promise.allSettled([streamController.startCall?.promise, streamController.pullCall?.promise, streamController.cancelCall?.promise]);\n    delete this.streamControllers[streamId];\n  }\n  destroy() {\n    this.comObj.removeEventListener(\"message\", this._onComObjOnMessage);\n  }\n}\n\n;// ./src/core/worker_stream.js\n\nclass PDFWorkerStream {\n  constructor(msgHandler) {\n    this._msgHandler = msgHandler;\n    this._contentLength = null;\n    this._fullRequestReader = null;\n    this._rangeRequestReaders = [];\n  }\n  getFullReader() {\n    assert(!this._fullRequestReader, \"PDFWorkerStream.getFullReader can only be called once.\");\n    this._fullRequestReader = new PDFWorkerStreamReader(this._msgHandler);\n    return this._fullRequestReader;\n  }\n  getRangeReader(begin, end) {\n    const reader = new PDFWorkerStreamRangeReader(begin, end, this._msgHandler);\n    this._rangeRequestReaders.push(reader);\n    return reader;\n  }\n  cancelAllRequests(reason) {\n    this._fullRequestReader?.cancel(reason);\n    for (const reader of this._rangeRequestReaders.slice(0)) {\n      reader.cancel(reason);\n    }\n  }\n}\nclass PDFWorkerStreamReader {\n  constructor(msgHandler) {\n    this._msgHandler = msgHandler;\n    this.onProgress = null;\n    this._contentLength = null;\n    this._isRangeSupported = false;\n    this._isStreamingSupported = false;\n    const readableStream = this._msgHandler.sendWithStream(\"GetReader\");\n    this._reader = readableStream.getReader();\n    this._headersReady = this._msgHandler.sendWithPromise(\"ReaderHeadersReady\").then(data => {\n      this._isStreamingSupported = data.isStreamingSupported;\n      this._isRangeSupported = data.isRangeSupported;\n      this._contentLength = data.contentLength;\n    });\n  }\n  get headersReady() {\n    return this._headersReady;\n  }\n  get contentLength() {\n    return this._contentLength;\n  }\n  get isStreamingSupported() {\n    return this._isStreamingSupported;\n  }\n  get isRangeSupported() {\n    return this._isRangeSupported;\n  }\n  async read() {\n    const {\n      value,\n      done\n    } = await this._reader.read();\n    if (done) {\n      return {\n        value: undefined,\n        done: true\n      };\n    }\n    return {\n      value: value.buffer,\n      done: false\n    };\n  }\n  cancel(reason) {\n    this._reader.cancel(reason);\n  }\n}\nclass PDFWorkerStreamRangeReader {\n  constructor(begin, end, msgHandler) {\n    this._msgHandler = msgHandler;\n    this.onProgress = null;\n    const readableStream = this._msgHandler.sendWithStream(\"GetRangeReader\", {\n      begin,\n      end\n    });\n    this._reader = readableStream.getReader();\n  }\n  get isStreamingSupported() {\n    return false;\n  }\n  async read() {\n    const {\n      value,\n      done\n    } = await this._reader.read();\n    if (done) {\n      return {\n        value: undefined,\n        done: true\n      };\n    }\n    return {\n      value: value.buffer,\n      done: false\n    };\n  }\n  cancel(reason) {\n    this._reader.cancel(reason);\n  }\n}\n\n;// ./src/core/worker.js\n\n\n\n\n\n\n\n\n\n\nclass WorkerTask {\n  constructor(name) {\n    this.name = name;\n    this.terminated = false;\n    this._capability = new PromiseCapability();\n  }\n  get finished() {\n    return this._capability.promise;\n  }\n  finish() {\n    this._capability.resolve();\n  }\n  terminate() {\n    this.terminated = true;\n  }\n  ensureNotTerminated() {\n    if (this.terminated) {\n      throw new Error(\"Worker task was terminated\");\n    }\n  }\n}\nclass WorkerMessageHandler {\n  static setup(handler, port) {\n    let testMessageProcessed = false;\n    handler.on(\"test\", function (data) {\n      if (testMessageProcessed) {\n        return;\n      }\n      testMessageProcessed = true;\n      handler.send(\"test\", data instanceof Uint8Array);\n    });\n    handler.on(\"configure\", function (data) {\n      setVerbosityLevel(data.verbosity);\n    });\n    handler.on(\"GetDocRequest\", function (data) {\n      return WorkerMessageHandler.createDocumentHandler(data, port);\n    });\n  }\n  static createDocumentHandler(docParams, port) {\n    let pdfManager;\n    let terminated = false;\n    let cancelXHRs = null;\n    const WorkerTasks = new Set();\n    const verbosity = getVerbosityLevel();\n    const {\n      docId,\n      apiVersion\n    } = docParams;\n    const workerVersion = \"4.1.0\";\n    if (apiVersion !== workerVersion) {\n      throw new Error(`The API version \"${apiVersion}\" does not match ` + `the Worker version \"${workerVersion}\".`);\n    }\n    const enumerableProperties = [];\n    for (const property in []) {\n      enumerableProperties.push(property);\n    }\n    if (enumerableProperties.length) {\n      throw new Error(\"The `Array.prototype` contains unexpected enumerable properties: \" + enumerableProperties.join(\", \") + \"; thus breaking e.g. `for...in` iteration of `Array`s.\");\n    }\n    const workerHandlerName = docId + \"_worker\";\n    let handler = new MessageHandler(workerHandlerName, docId, port);\n    function ensureNotTerminated() {\n      if (terminated) {\n        throw new Error(\"Worker was terminated\");\n      }\n    }\n    function startWorkerTask(task) {\n      WorkerTasks.add(task);\n    }\n    function finishWorkerTask(task) {\n      task.finish();\n      WorkerTasks.delete(task);\n    }\n    async function loadDocument(recoveryMode) {\n      await pdfManager.ensureDoc(\"checkHeader\");\n      await pdfManager.ensureDoc(\"parseStartXRef\");\n      await pdfManager.ensureDoc(\"parse\", [recoveryMode]);\n      await pdfManager.ensureDoc(\"checkFirstPage\", [recoveryMode]);\n      await pdfManager.ensureDoc(\"checkLastPage\", [recoveryMode]);\n      const isPureXfa = await pdfManager.ensureDoc(\"isPureXfa\");\n      if (isPureXfa) {\n        const task = new WorkerTask(\"loadXfaFonts\");\n        startWorkerTask(task);\n        await Promise.all([pdfManager.loadXfaFonts(handler, task).catch(reason => {}).then(() => finishWorkerTask(task)), pdfManager.loadXfaImages()]);\n      }\n      const [numPages, fingerprints] = await Promise.all([pdfManager.ensureDoc(\"numPages\"), pdfManager.ensureDoc(\"fingerprints\")]);\n      const htmlForXfa = isPureXfa ? await pdfManager.ensureDoc(\"htmlForXfa\") : null;\n      return {\n        numPages,\n        fingerprints,\n        htmlForXfa\n      };\n    }\n    function getPdfManager({\n      data,\n      password,\n      disableAutoFetch,\n      rangeChunkSize,\n      length,\n      docBaseUrl,\n      enableXfa,\n      evaluatorOptions\n    }) {\n      const pdfManagerArgs = {\n        source: null,\n        disableAutoFetch,\n        docBaseUrl,\n        docId,\n        enableXfa,\n        evaluatorOptions,\n        handler,\n        length,\n        password,\n        rangeChunkSize\n      };\n      const pdfManagerCapability = new PromiseCapability();\n      let newPdfManager;\n      if (data) {\n        try {\n          pdfManagerArgs.source = data;\n          newPdfManager = new LocalPdfManager(pdfManagerArgs);\n          pdfManagerCapability.resolve(newPdfManager);\n        } catch (ex) {\n          pdfManagerCapability.reject(ex);\n        }\n        return pdfManagerCapability.promise;\n      }\n      let pdfStream,\n        cachedChunks = [];\n      try {\n        pdfStream = new PDFWorkerStream(handler);\n      } catch (ex) {\n        pdfManagerCapability.reject(ex);\n        return pdfManagerCapability.promise;\n      }\n      const fullRequest = pdfStream.getFullReader();\n      fullRequest.headersReady.then(function () {\n        if (!fullRequest.isRangeSupported) {\n          return;\n        }\n        pdfManagerArgs.source = pdfStream;\n        pdfManagerArgs.length = fullRequest.contentLength;\n        pdfManagerArgs.disableAutoFetch ||= fullRequest.isStreamingSupported;\n        newPdfManager = new NetworkPdfManager(pdfManagerArgs);\n        for (const chunk of cachedChunks) {\n          newPdfManager.sendProgressiveData(chunk);\n        }\n        cachedChunks = [];\n        pdfManagerCapability.resolve(newPdfManager);\n        cancelXHRs = null;\n      }).catch(function (reason) {\n        pdfManagerCapability.reject(reason);\n        cancelXHRs = null;\n      });\n      let loaded = 0;\n      const flushChunks = function () {\n        const pdfFile = arrayBuffersToBytes(cachedChunks);\n        if (length && pdfFile.length !== length) {\n          warn(\"reported HTTP length is different from actual\");\n        }\n        try {\n          pdfManagerArgs.source = pdfFile;\n          newPdfManager = new LocalPdfManager(pdfManagerArgs);\n          pdfManagerCapability.resolve(newPdfManager);\n        } catch (ex) {\n          pdfManagerCapability.reject(ex);\n        }\n        cachedChunks = [];\n      };\n      new Promise(function (resolve, reject) {\n        const readChunk = function ({\n          value,\n          done\n        }) {\n          try {\n            ensureNotTerminated();\n            if (done) {\n              if (!newPdfManager) {\n                flushChunks();\n              }\n              cancelXHRs = null;\n              return;\n            }\n            loaded += value.byteLength;\n            if (!fullRequest.isStreamingSupported) {\n              handler.send(\"DocProgress\", {\n                loaded,\n                total: Math.max(loaded, fullRequest.contentLength || 0)\n              });\n            }\n            if (newPdfManager) {\n              newPdfManager.sendProgressiveData(value);\n            } else {\n              cachedChunks.push(value);\n            }\n            fullRequest.read().then(readChunk, reject);\n          } catch (e) {\n            reject(e);\n          }\n        };\n        fullRequest.read().then(readChunk, reject);\n      }).catch(function (e) {\n        pdfManagerCapability.reject(e);\n        cancelXHRs = null;\n      });\n      cancelXHRs = function (reason) {\n        pdfStream.cancelAllRequests(reason);\n      };\n      return pdfManagerCapability.promise;\n    }\n    function setupDoc(data) {\n      function onSuccess(doc) {\n        ensureNotTerminated();\n        handler.send(\"GetDoc\", {\n          pdfInfo: doc\n        });\n      }\n      function onFailure(ex) {\n        ensureNotTerminated();\n        if (ex instanceof PasswordException) {\n          const task = new WorkerTask(`PasswordException: response ${ex.code}`);\n          startWorkerTask(task);\n          handler.sendWithPromise(\"PasswordRequest\", ex).then(function ({\n            password\n          }) {\n            finishWorkerTask(task);\n            pdfManager.updatePassword(password);\n            pdfManagerReady();\n          }).catch(function () {\n            finishWorkerTask(task);\n            handler.send(\"DocException\", ex);\n          });\n        } else if (ex instanceof InvalidPDFException || ex instanceof MissingPDFException || ex instanceof UnexpectedResponseException || ex instanceof UnknownErrorException) {\n          handler.send(\"DocException\", ex);\n        } else {\n          handler.send(\"DocException\", new UnknownErrorException(ex.message, ex.toString()));\n        }\n      }\n      function pdfManagerReady() {\n        ensureNotTerminated();\n        loadDocument(false).then(onSuccess, function (reason) {\n          ensureNotTerminated();\n          if (!(reason instanceof XRefParseException)) {\n            onFailure(reason);\n            return;\n          }\n          pdfManager.requestLoadedStream().then(function () {\n            ensureNotTerminated();\n            loadDocument(true).then(onSuccess, onFailure);\n          });\n        });\n      }\n      ensureNotTerminated();\n      getPdfManager(data).then(function (newPdfManager) {\n        if (terminated) {\n          newPdfManager.terminate(new AbortException(\"Worker was terminated.\"));\n          throw new Error(\"Worker was terminated\");\n        }\n        pdfManager = newPdfManager;\n        pdfManager.requestLoadedStream(true).then(stream => {\n          handler.send(\"DataLoaded\", {\n            length: stream.bytes.byteLength\n          });\n        });\n      }).then(pdfManagerReady, onFailure);\n    }\n    handler.on(\"GetPage\", function (data) {\n      return pdfManager.getPage(data.pageIndex).then(function (page) {\n        return Promise.all([pdfManager.ensure(page, \"rotate\"), pdfManager.ensure(page, \"ref\"), pdfManager.ensure(page, \"userUnit\"), pdfManager.ensure(page, \"view\")]).then(function ([rotate, ref, userUnit, view]) {\n          return {\n            rotate,\n            ref,\n            userUnit,\n            view\n          };\n        });\n      });\n    });\n    handler.on(\"GetPageIndex\", function (data) {\n      const pageRef = Ref.get(data.num, data.gen);\n      return pdfManager.ensureCatalog(\"getPageIndex\", [pageRef]);\n    });\n    handler.on(\"GetDestinations\", function (data) {\n      return pdfManager.ensureCatalog(\"destinations\");\n    });\n    handler.on(\"GetDestination\", function (data) {\n      return pdfManager.ensureCatalog(\"getDestination\", [data.id]);\n    });\n    handler.on(\"GetPageLabels\", function (data) {\n      return pdfManager.ensureCatalog(\"pageLabels\");\n    });\n    handler.on(\"GetPageLayout\", function (data) {\n      return pdfManager.ensureCatalog(\"pageLayout\");\n    });\n    handler.on(\"GetPageMode\", function (data) {\n      return pdfManager.ensureCatalog(\"pageMode\");\n    });\n    handler.on(\"GetViewerPreferences\", function (data) {\n      return pdfManager.ensureCatalog(\"viewerPreferences\");\n    });\n    handler.on(\"GetOpenAction\", function (data) {\n      return pdfManager.ensureCatalog(\"openAction\");\n    });\n    handler.on(\"GetAttachments\", function (data) {\n      return pdfManager.ensureCatalog(\"attachments\");\n    });\n    handler.on(\"GetDocJSActions\", function (data) {\n      return pdfManager.ensureCatalog(\"jsActions\");\n    });\n    handler.on(\"GetPageJSActions\", function ({\n      pageIndex\n    }) {\n      return pdfManager.getPage(pageIndex).then(function (page) {\n        return pdfManager.ensure(page, \"jsActions\");\n      });\n    });\n    handler.on(\"GetOutline\", function (data) {\n      return pdfManager.ensureCatalog(\"documentOutline\");\n    });\n    handler.on(\"GetOptionalContentConfig\", function (data) {\n      return pdfManager.ensureCatalog(\"optionalContentConfig\");\n    });\n    handler.on(\"GetPermissions\", function (data) {\n      return pdfManager.ensureCatalog(\"permissions\");\n    });\n    handler.on(\"GetMetadata\", function (data) {\n      return Promise.all([pdfManager.ensureDoc(\"documentInfo\"), pdfManager.ensureCatalog(\"metadata\")]);\n    });\n    handler.on(\"GetMarkInfo\", function (data) {\n      return pdfManager.ensureCatalog(\"markInfo\");\n    });\n    handler.on(\"GetData\", function (data) {\n      return pdfManager.requestLoadedStream().then(function (stream) {\n        return stream.bytes;\n      });\n    });\n    handler.on(\"GetAnnotations\", function ({\n      pageIndex,\n      intent\n    }) {\n      return pdfManager.getPage(pageIndex).then(function (page) {\n        const task = new WorkerTask(`GetAnnotations: page ${pageIndex}`);\n        startWorkerTask(task);\n        return page.getAnnotationsData(handler, task, intent).then(data => {\n          finishWorkerTask(task);\n          return data;\n        }, reason => {\n          finishWorkerTask(task);\n          throw reason;\n        });\n      });\n    });\n    handler.on(\"GetFieldObjects\", function (data) {\n      return pdfManager.ensureDoc(\"fieldObjects\");\n    });\n    handler.on(\"HasJSActions\", function (data) {\n      return pdfManager.ensureDoc(\"hasJSActions\");\n    });\n    handler.on(\"GetCalculationOrderIds\", function (data) {\n      return pdfManager.ensureDoc(\"calculationOrderIds\");\n    });\n    handler.on(\"SaveDocument\", async function ({\n      isPureXfa,\n      numPages,\n      annotationStorage,\n      filename\n    }) {\n      const globalPromises = [pdfManager.requestLoadedStream(), pdfManager.ensureCatalog(\"acroForm\"), pdfManager.ensureCatalog(\"acroFormRef\"), pdfManager.ensureDoc(\"startXRef\"), pdfManager.ensureDoc(\"xref\"), pdfManager.ensureDoc(\"linearization\"), pdfManager.ensureCatalog(\"structTreeRoot\")];\n      const promises = [];\n      const newAnnotationsByPage = !isPureXfa ? getNewAnnotationsMap(annotationStorage) : null;\n      const [stream, acroForm, acroFormRef, startXRef, xref, linearization, _structTreeRoot] = await Promise.all(globalPromises);\n      const catalogRef = xref.trailer.getRaw(\"Root\") || null;\n      let structTreeRoot;\n      if (newAnnotationsByPage) {\n        if (!_structTreeRoot) {\n          if (await StructTreeRoot.canCreateStructureTree({\n            catalogRef,\n            pdfManager,\n            newAnnotationsByPage\n          })) {\n            structTreeRoot = null;\n          }\n        } else if (await _structTreeRoot.canUpdateStructTree({\n          pdfManager,\n          xref,\n          newAnnotationsByPage\n        })) {\n          structTreeRoot = _structTreeRoot;\n        }\n        const imagePromises = AnnotationFactory.generateImages(annotationStorage.values(), xref, pdfManager.evaluatorOptions.isOffscreenCanvasSupported);\n        const newAnnotationPromises = structTreeRoot === undefined ? promises : [];\n        for (const [pageIndex, annotations] of newAnnotationsByPage) {\n          newAnnotationPromises.push(pdfManager.getPage(pageIndex).then(page => {\n            const task = new WorkerTask(`Save (editor): page ${pageIndex}`);\n            return page.saveNewAnnotations(handler, task, annotations, imagePromises).finally(function () {\n              finishWorkerTask(task);\n            });\n          }));\n        }\n        if (structTreeRoot === null) {\n          promises.push(Promise.all(newAnnotationPromises).then(async newRefs => {\n            await StructTreeRoot.createStructureTree({\n              newAnnotationsByPage,\n              xref,\n              catalogRef,\n              pdfManager,\n              newRefs\n            });\n            return newRefs;\n          }));\n        } else if (structTreeRoot) {\n          promises.push(Promise.all(newAnnotationPromises).then(async newRefs => {\n            await structTreeRoot.updateStructureTree({\n              newAnnotationsByPage,\n              pdfManager,\n              newRefs\n            });\n            return newRefs;\n          }));\n        }\n      }\n      if (isPureXfa) {\n        promises.push(pdfManager.serializeXfaData(annotationStorage));\n      } else {\n        for (let pageIndex = 0; pageIndex < numPages; pageIndex++) {\n          promises.push(pdfManager.getPage(pageIndex).then(function (page) {\n            const task = new WorkerTask(`Save: page ${pageIndex}`);\n            return page.save(handler, task, annotationStorage).finally(function () {\n              finishWorkerTask(task);\n            });\n          }));\n        }\n      }\n      const refs = await Promise.all(promises);\n      let newRefs = [];\n      let xfaData = null;\n      if (isPureXfa) {\n        xfaData = refs[0];\n        if (!xfaData) {\n          return stream.bytes;\n        }\n      } else {\n        newRefs = refs.flat(2);\n        if (newRefs.length === 0) {\n          return stream.bytes;\n        }\n      }\n      const needAppearances = acroFormRef && acroForm instanceof Dict && newRefs.some(ref => ref.needAppearances);\n      const xfa = acroForm instanceof Dict && acroForm.get(\"XFA\") || null;\n      let xfaDatasetsRef = null;\n      let hasXfaDatasetsEntry = false;\n      if (Array.isArray(xfa)) {\n        for (let i = 0, ii = xfa.length; i < ii; i += 2) {\n          if (xfa[i] === \"datasets\") {\n            xfaDatasetsRef = xfa[i + 1];\n            hasXfaDatasetsEntry = true;\n          }\n        }\n        if (xfaDatasetsRef === null) {\n          xfaDatasetsRef = xref.getNewTemporaryRef();\n        }\n      } else if (xfa) {\n        warn(\"Unsupported XFA type.\");\n      }\n      let newXrefInfo = Object.create(null);\n      if (xref.trailer) {\n        const infoObj = Object.create(null);\n        const xrefInfo = xref.trailer.get(\"Info\") || null;\n        if (xrefInfo instanceof Dict) {\n          xrefInfo.forEach((key, value) => {\n            if (typeof value === \"string\") {\n              infoObj[key] = stringToPDFString(value);\n            }\n          });\n        }\n        newXrefInfo = {\n          rootRef: catalogRef,\n          encryptRef: xref.trailer.getRaw(\"Encrypt\") || null,\n          newRef: xref.getNewTemporaryRef(),\n          infoRef: xref.trailer.getRaw(\"Info\") || null,\n          info: infoObj,\n          fileIds: xref.trailer.get(\"ID\") || null,\n          startXRef: linearization ? startXRef : xref.lastXRefStreamPos ?? startXRef,\n          filename\n        };\n      }\n      return incrementalUpdate({\n        originalData: stream.bytes,\n        xrefInfo: newXrefInfo,\n        newRefs,\n        xref,\n        hasXfa: !!xfa,\n        xfaDatasetsRef,\n        hasXfaDatasetsEntry,\n        needAppearances,\n        acroFormRef,\n        acroForm,\n        xfaData,\n        useXrefStream: isDict(xref.topDict, \"XRef\")\n      }).finally(() => {\n        xref.resetNewTemporaryRef();\n      });\n    });\n    handler.on(\"GetOperatorList\", function (data, sink) {\n      const pageIndex = data.pageIndex;\n      const imageOutLlamaParse = data.imageOutLlamaParse || \"./\";\n      const disableImageExtraction = data.disableImageExtraction || false;\n      pdfManager.getPage(pageIndex).then(function (page) {\n        const task = new WorkerTask(`GetOperatorList: page ${pageIndex}`);\n        startWorkerTask(task);\n        const start = verbosity >= VerbosityLevel.INFOS ? Date.now() : 0;\n        page.getOperatorList({\n          handler,\n          sink,\n          task,\n          intent: data.intent,\n          cacheKey: data.cacheKey,\n          annotationStorage: data.annotationStorage,\n          imageOutLlamaParse: imageOutLlamaParse,\n          disableImageExtraction: disableImageExtraction\n        }).then(function (operatorListInfo) {\n          finishWorkerTask(task);\n          if (start) {\n            info(`page=${pageIndex + 1} - getOperatorList: time=` + `${Date.now() - start}ms, len=${operatorListInfo.length}`);\n          }\n          sink.close();\n        }, function (reason) {\n          finishWorkerTask(task);\n          if (task.terminated) {\n            return;\n          }\n          sink.error(reason);\n        });\n      });\n    });\n    handler.on(\"GetTextContent\", function (data, sink) {\n      const {\n        pageIndex,\n        includeMarkedContent,\n        disableNormalization\n      } = data;\n      pdfManager.getPage(pageIndex).then(function (page) {\n        const task = new WorkerTask(\"GetTextContent: page \" + pageIndex);\n        startWorkerTask(task);\n        const start = verbosity >= VerbosityLevel.INFOS ? Date.now() : 0;\n        page.extractTextContent({\n          handler,\n          task,\n          sink,\n          includeMarkedContent,\n          disableNormalization\n        }).then(function () {\n          finishWorkerTask(task);\n          if (start) {\n            info(`page=${pageIndex + 1} - getTextContent: time=` + `${Date.now() - start}ms`);\n          }\n          sink.close();\n        }, function (reason) {\n          finishWorkerTask(task);\n          if (task.terminated) {\n            return;\n          }\n          sink.error(reason);\n        });\n      });\n    });\n    handler.on(\"GetStructTree\", function (data) {\n      return pdfManager.getPage(data.pageIndex).then(function (page) {\n        return pdfManager.ensure(page, \"getStructTree\");\n      });\n    });\n    handler.on(\"FontFallback\", function (data) {\n      return pdfManager.fontFallback(data.id, handler);\n    });\n    handler.on(\"Cleanup\", function (data) {\n      return pdfManager.cleanup(true);\n    });\n    handler.on(\"Terminate\", function (data) {\n      terminated = true;\n      const waitOn = [];\n      if (pdfManager) {\n        pdfManager.terminate(new AbortException(\"Worker was terminated.\"));\n        const cleanupPromise = pdfManager.cleanup();\n        waitOn.push(cleanupPromise);\n        pdfManager = null;\n      } else {\n        clearGlobalCaches();\n      }\n      if (cancelXHRs) {\n        cancelXHRs(new AbortException(\"Worker was terminated.\"));\n      }\n      for (const task of WorkerTasks) {\n        waitOn.push(task.finished);\n        task.terminate();\n      }\n      return Promise.all(waitOn).then(function () {\n        handler.destroy();\n        handler = null;\n      });\n    });\n    handler.on(\"Ready\", function (data) {\n      setupDoc(docParams);\n      docParams = null;\n    });\n    return workerHandlerName;\n  }\n  static initializeFromPort(port) {\n    const handler = new MessageHandler(\"worker\", \"main\", port);\n    WorkerMessageHandler.setup(handler, port);\n    handler.send(\"ready\", null);\n  }\n}\nfunction isMessagePort(maybePort) {\n  return typeof maybePort.postMessage === \"function\" && \"onmessage\" in maybePort;\n}\nif (typeof window === \"undefined\" && !isNodeJS && typeof self !== \"undefined\" && isMessagePort(self)) {\n  WorkerMessageHandler.initializeFromPort(self);\n}\n\n;// ./src/pdf.worker.js\n\nconst pdfjsVersion = \"4.1.0\";\nconst pdfjsBuild = \"849f8548b1\";\n\nexport { WorkerMessageHandler };\n\n//# sourceMappingURL=pdf.worker.mjs.map"
  },
  {
    "path": "src/vendor/pdfjs/standard_fonts/LICENSE_FOXIT",
    "content": "// Copyright 2014 PDFium Authors. All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//    * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//    * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//    * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "src/vendor/pdfjs/standard_fonts/LICENSE_LIBERATION",
    "content": "Digitized data copyright (c) 2010 Google Corporation\n\twith Reserved Font Arimo, Tinos and Cousine.\nCopyright (c) 2012 Red Hat, Inc.\n\twith Reserved Font Name Liberation.\n\nThis Font Software is licensed under the SIL Open Font License,\nVersion 1.1.\n\nThis license is copied below, and is also available with a FAQ at:\nhttp://scripts.sil.org/OFL\n\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n\nPREAMBLE The goals of the Open Font License (OFL) are to stimulate\nworldwide development of collaborative font projects, to support the font\ncreation efforts of academic and linguistic communities, and to provide\na free and open framework in which fonts may be shared and improved in\npartnership with others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves.\nThe fonts, including any derivative works, can be bundled, embedded,\nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works.  The fonts and derivatives,\nhowever, cannot be released under any other type of license.  The\nrequirement for fonts to remain under this license does not apply to\nany document created using the fonts or their derivatives.\n\n \n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such.\nThis may include source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components\nas distributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting ? in part or in whole ?\nany of the components of the Original Version, by changing formats or\nby porting the Font Software to a new environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical writer\nor other person who contributed to the Font Software.\n\n\nPERMISSION & CONDITIONS\n\nPermission is hereby granted, free of charge, to any person obtaining a\ncopy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,in\n   Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\n   redistributed and/or sold with any software, provided that each copy\n   contains the above copyright notice and this license. These can be\n   included either as stand-alone text files, human-readable headers or\n   in the appropriate machine-readable metadata fields within text or\n   binary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\n   Name(s) unless explicit written permission is granted by the\n   corresponding Copyright Holder. This restriction only applies to the\n   primary font name as presented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\n   Software shall not be used to promote, endorse or advertise any\n   Modified Version, except to acknowledge the contribution(s) of the\n   Copyright Holder(s) and the Author(s) or with their explicit written\n   permission.\n\n5) The Font Software, modified or unmodified, in part or in whole, must\n   be distributed entirely under this license, and must not be distributed\n   under any other license. The requirement for fonts to remain under\n   this license does not apply to any document created using the Font\n   Software.\n\n\n \nTERMINATION\nThis license becomes null and void if any of the above conditions are not met.\n\n \n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT.  IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER\nDEALINGS IN THE FONT SOFTWARE.\n\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"node\",\n    \"lib\": [\"ES2022\"],\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"./\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"resolveJsonModule\": true,\n    \"declaration\": true,\n    \"declarationMap\": true,\n    \"sourceMap\": true,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"noImplicitReturns\": true,\n    \"noFallthroughCasesInSwitch\": true\n  },\n  \"include\": [\n    \"src/**/*\",\n    \"cli/**/*\"\n  ],\n  \"exclude\": [\n    \"node_modules\",\n    \"dist\"\n  ]\n}\n"
  },
  {
    "path": "typedoc.json",
    "content": "{\n  \"$schema\": \"https://typedoc.org/schema.json\",\n  \"entryPoints\": [\"./src/lib.ts\"],\n  \"plugin\": [\"typedoc-plugin-markdown\"],\n  \"out\": \"./docs/src/content/docs/liteparse/.api-tmp\",\n  \"outputFileStrategy\": \"modules\",\n  \"flattenOutputFiles\": true,\n  \"hidePageHeader\": true,\n  \"hidePageTitle\": true,\n  \"hideGroupHeadings\": false,\n  \"excludeInternal\": true,\n  \"excludePrivate\": true,\n  \"excludeProtected\": true,\n  \"readme\": \"none\",\n  \"disableSources\": false\n}\n"
  },
  {
    "path": "vitest.config.ts",
    "content": "import { defineConfig } from \"vitest/config\";\n\nexport default defineConfig({\n  test: {\n    globals: true,\n    environment: \"node\",\n    testTimeout: 30000,\n    hookTimeout: 30000,\n    teardownTimeout: 30000,\n    coverage: {\n      provider: \"v8\",\n      reporter: [\"text\", \"json\", \"html\"],\n      exclude: [\"node_modules/\", \"dist/\"],\n    },\n    unstubEnvs: true,\n  },\n  resolve: {\n    alias: {\n      \"@\": \"./src\",\n    },\n    conditions: [\"node\", \"import\", \"module\", \"default\"],\n  },\n  esbuild: {\n    target: \"es2022\",\n  },\n});\n"
  }
]